Problem p01431 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> P;
typedef pair<int, P> P1;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define rep(i, x) for (int i = 0; i < x; i++)
#define rep1(i, x) for (int i = 1; i <= x; i++)
#define rrep(i, x) for (int i = x - 1; i >= 0; i--)
#define rrep1(i, x) for (int i = x; i > 0; i--)
#define sor(v) sort(v.begin(), v.end())
#define rev(s) reverse(s.begin(), s.end())
#define lb(vec, a) lower_bound(vec.begin(), vec.end(), a)
#define ub(vec, a) upper_bound(vec.begin(), vec.end(), a)
#define uniq(vec) vec.erase(unique(vec.begin(), vec.end()), vec.end())
#define mp1(a, b, c) P1(a, P(b, c))

const int INF = 1000000000;
const int dir_4[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
const int dir_8[8][2] = {{1, 0},  {1, 1},   {0, 1},  {-1, 1},
                         {-1, 0}, {-1, -1}, {0, -1}, {1, -1}};

const int MAX_V = 12;
struct UF {
  int par[MAX_V], r[MAX_V];
  void init() {
    rep(i, MAX_V) {
      par[i] = i;
      r[i] = 0;
    }
  }
  int find(int x) {
    if (x == par[x])
      return x;
    return par[x] = find(par[x]);
  }
  bool same(int x, int y) { return find(x) == find(y); }
  void unit(int x, int y) {
    if (same(x, y))
      return;
    x = find(x);
    y = find(y);
    if (r[x] < r[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (r[x] == r[y]) {
        r[x]++;
      }
    }
  }
  bool operator<(UF y) {
    rep(i, MAX_V) {
      rep(j, MAX_V) {
        if (y.same(i, j)) {
          if (!this->same(i, j))
            return false;
        } else {
          if (this->same(i, j))
            return true;
        }
      }
    }
    return false;
  }
  bool operator==(UF y) {
    rep(i, MAX_V) {
      rep(j, MAX_V) {
        if (y.same(i, j)) {
          if (!this->same(i, j))
            return false;
        } else {
          if (this->same(i, j))
            return false;
        }
      }
    }
    return true;
  }
};
UF uf;

int h, w;
struct A {
  bool black[12];
  UF uf;
  bool operator<(A y) const {
    rep(i, w) {
      if (y.black[i] && (!this->black[i]))
        return true;
      if ((!y.black[i]) && this->black[i])
        return false;
    }
    return y.uf < this->uf;
  }
  bool operator==(A y) const {
    rep(i, w) {
      if (y.black[i] && (!this->black[i]))
        return false;
      if ((!y.black[i]) && this->black[i])
        return false;
    }
    return y.uf == this->uf;
  }
};

int main() {
  static map<A, P> id;
  static A abcde[6000];
  static int cnt_abcde = 0;
  static A id_[6000];
  static int memo[6000];
  scanf("%d%d", &h, &w);

  rep(i, (1 << w)) {
    A a;
    a.uf.init();
    int cnt = 0, cnt_ = 0, loc[6];
    rep(j, w) a.black[j] = (((i >> j) & 1) == 1);
    rep(j, w - 1) if ((!a.black[j]) && (!a.black[j + 1])) goto Next;
    rep(j, w) {
      if ((j == 0 && a.black[0]) || ((!a.black[j - 1]) && a.black[j])) {
        loc[cnt++] = j;
      }
      if (a.black[j])
        cnt_++;
    }
    rep(k, w - 1) if (a.black[k] && a.black[k + 1]) a.uf.unit(k, k + 1);
    abcde[cnt_abcde++] = a;
    rep(j, (1 << ((cnt * (cnt - 1))) / 2)) {
      a.uf.init();
      rep(k, w - 1) if (a.black[k] && a.black[k + 1]) a.uf.unit(k, k + 1);
      int k = 0;
      rep(x, cnt) {
        for (int y = x + 1; y < cnt; y++) {
          if ((j >> k) & 1)
            a.uf.unit(loc[x], loc[y]);
          k++;
        }
      }
      if (id.find(a) == id.end()) {
        id_[id.size()] = a;
        memo[id.size()] = cnt_;
        id[a] = P(id.size(), cnt_);
      }
    }
  Next:;
  }

  int s = id.size();

  char c[12][12];
  rep(i, h) {
    scanf("\\n");
    rep(j, w) { scanf("%c", &c[i][j]); }
  }

  int dp[2][6000];
  int pre[12][6000];
  int t = 0, t_ = 1;
  rep(i, 6000) dp[0][i] = -INF;
  rep(i, s) {
    rep(j, w) {
      if (c[0][j] == '#' && (!id_[i].black[j]))
        goto Next1;
      if (c[0][j] == '.' && id_[i].black[j])
        goto Next1;
    }
    rep(j, w) {
      bool tt = false;
      for (int k = j + 1; k < w; k++) {
        if (!id_[i].black[k])
          tt = true;
        if (tt && id_[i].uf.same(j, k))
          goto Next1;
      }
    }
    dp[0][i] = memo[i];
  Next1:;
  }
  rep(x, h - 1) {
    rep(i, 6000) dp[t_][i] = -INF;
    rep(i, s) {
      if (dp[t][i] == -INF)
        continue;
      rep(ppp, cnt_abcde) {
        A a = abcde[ppp], cop = id_[i];
        bool used[12];
        rep(j, w) if ((!a.black[j]) && (!id_[i].black[j])) goto Next3;
        rep(j, w) {
          if (c[x + 1][j] == '#' && (!a.black[j]))
            goto Next3;
          if (c[x + 1][j] == '.' && a.black[j])
            goto Next3;
        }
        uf.init();
        rep(j, w) used[j] = false;
        rep(j, w) {
          if (a.black[j] && id_[i].black[j] && !used[a.uf.find(j)]) {
            for (int k = j + 1; k < w; k++) {
              if (a.black[k]) {
                if (a.uf.same(j, k)) {
                  if (uf.same(id_[i].uf.find(j), id_[i].uf.find(k)))
                    goto Next3;
                  else
                    uf.unit(id_[i].uf.find(j), id_[i].uf.find(k));
                }
              } else
                break;
            }
            used[a.uf.find(j)] = true;
          }
        }
        rep(j, w) {
          if (a.black[j] && id_[i].black[j]) {
            for (int k = j + 1; k < w; k++)
              if (a.black[k] && id_[i].black[k]) {
                if (id_[i].uf.same(j, k))
                  a.uf.unit(j, k);
              }
          }
        }
        if (!(w == 1 && x == h - 2)) {
          rep(j, w) if (a.black[j] && cop.black[j]) cop.uf.unit(j, 11);
          rep(j, w) if (cop.black[j] && (!cop.uf.same(j, 11))) goto Next3;
        }

        dp[t_][id[a].fr] = max(dp[t_][id[a].fr], dp[t][i] + id[a].sc);
      Next3:;
      }
    }
    swap(t, t_);
  }

  int ret = -1;
  rep(i, s) {
    if (dp[t][i] == -INF)
      continue;
    rep(j, w) for (int k = j + 1; k < w; k++) {
      if (id_[i].black[j] && id_[i].black[k] && (!id_[i].uf.same(j, k)))
        goto Next4;
    }
    ret = max(ret, dp[t][i]);
  Next4:;
  }
  cout << ret << endl;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> P;
typedef pair<int, P> P1;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define rep(i, x) for (int i = 0; i < x; i++)
#define rep1(i, x) for (int i = 1; i <= x; i++)
#define rrep(i, x) for (int i = x - 1; i >= 0; i--)
#define rrep1(i, x) for (int i = x; i > 0; i--)
#define sor(v) sort(v.begin(), v.end())
#define rev(s) reverse(s.begin(), s.end())
#define lb(vec, a) lower_bound(vec.begin(), vec.end(), a)
#define ub(vec, a) upper_bound(vec.begin(), vec.end(), a)
#define uniq(vec) vec.erase(unique(vec.begin(), vec.end()), vec.end())
#define mp1(a, b, c) P1(a, P(b, c))

const int INF = 1000000000;
const int dir_4[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
const int dir_8[8][2] = {{1, 0},  {1, 1},   {0, 1},  {-1, 1},
                         {-1, 0}, {-1, -1}, {0, -1}, {1, -1}};

const int MAX_V = 12;
struct UF {
  int par[MAX_V], r[MAX_V];
  void init() {
    rep(i, MAX_V) {
      par[i] = i;
      r[i] = 0;
    }
  }
  int find(int x) {
    if (x == par[x])
      return x;
    return par[x] = find(par[x]);
  }
  bool same(int x, int y) { return find(x) == find(y); }
  void unit(int x, int y) {
    if (same(x, y))
      return;
    x = find(x);
    y = find(y);
    if (r[x] < r[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (r[x] == r[y]) {
        r[x]++;
      }
    }
  }
  bool operator<(UF y) {
    rep(i, MAX_V) {
      rep(j, MAX_V) {
        if (y.same(i, j)) {
          if (!this->same(i, j))
            return false;
        } else {
          if (this->same(i, j))
            return true;
        }
      }
    }
    return false;
  }
  bool operator==(UF y) {
    rep(i, MAX_V) {
      rep(j, MAX_V) {
        if (y.same(i, j)) {
          if (!this->same(i, j))
            return false;
        } else {
          if (this->same(i, j))
            return false;
        }
      }
    }
    return true;
  }
};
UF uf;

int h, w;
struct A {
  bool black[12];
  UF uf;
  bool operator<(A y) const {
    rep(i, w) {
      if (y.black[i] && (!this->black[i]))
        return true;
      if ((!y.black[i]) && this->black[i])
        return false;
    }
    return y.uf < this->uf;
  }
  bool operator==(A y) const {
    rep(i, w) {
      if (y.black[i] && (!this->black[i]))
        return false;
      if ((!y.black[i]) && this->black[i])
        return false;
    }
    return y.uf == this->uf;
  }
};

int main() {
  static map<A, P> id;
  static A abcde[6000];
  static int cnt_abcde = 0;
  static A id_[6000];
  static int memo[6000];
  scanf("%d%d", &h, &w);

  rep(i, (1 << w)) {
    A a;
    a.uf.init();
    int cnt = 0, cnt_ = 0, loc[6];
    rep(j, w) a.black[j] = (((i >> j) & 1) == 1);
    rep(j, w - 1) if ((!a.black[j]) && (!a.black[j + 1])) goto Next;
    rep(j, w) {
      if ((j == 0 && a.black[0]) || ((!a.black[j - 1]) && a.black[j])) {
        loc[cnt++] = j;
      }
      if (a.black[j])
        cnt_++;
    }
    rep(k, w - 1) if (a.black[k] && a.black[k + 1]) a.uf.unit(k, k + 1);
    abcde[cnt_abcde++] = a;
    rep(j, (1 << ((cnt * (cnt - 1))) / 2)) {
      a.uf.init();
      rep(k, w - 1) if (a.black[k] && a.black[k + 1]) a.uf.unit(k, k + 1);
      int k = 0;
      rep(x, cnt) {
        for (int y = x + 1; y < cnt; y++) {
          if ((j >> k) & 1)
            a.uf.unit(loc[x], loc[y]);
          k++;
        }
      }
      if (id.find(a) == id.end()) {
        id_[id.size()] = a;
        memo[id.size()] = cnt_;
        id[a] = P(id.size(), cnt_);
      }
    }
  Next:;
  }

  int s = id.size();
  /*rep(i,2888){
          i = 2887;
          printf("%d:",i);
          rep(j,w)printf("%d ",id_[i].black[j]?1:0);
          rep(j,w){
                  rep(k,w){
                          printf("%d ",id_[i].uf.same(j,k)?1:0);
                  }
                  puts("");
          }
          printf(";%d\\n",memo[i]);
  }*/
  /*rep(i,s){
          printf("%d:",i);
          rep(j,w)printf("%d ",id_[i].black[j]?1:0);
          printf(";%d\\n",memo[i]);
  }*/

  char c[12][12];
  rep(i, h) {
    scanf("\\n");
    rep(j, w) { scanf("%c", &c[i][j]); }
  }

  int dp[2][6000];
  int pre[12][6000];
  int t = 0, t_ = 1;
  rep(i, 6000) dp[0][i] = -INF;
  rep(i, s) {
    rep(j, w) {
      if (c[0][j] == '#' && (!id_[i].black[j]))
        goto Next1;
      if (c[0][j] == '.' && id_[i].black[j])
        goto Next1;
    }
    rep(j, w - 1) {
      if (id_[i].black[j] && id_[i].black[j + 1] && !id_[i].uf.same(j, j + 1))
        goto Next1;
    }
    dp[0][i] = memo[i];
  Next1:;
  }
  /*rep(i,s){
          printf("%d:%d\\n",i,dp[t][i]);
  }puts("");*/
  rep(x, h - 1) {
    rep(i, 6000) dp[t_][i] = -INF;
    rep(i, s) {
      if (dp[t][i] == -INF)
        continue;
      rep(ppp, cnt_abcde) {
        A a = abcde[ppp], cop = id_[i];
        bool used[12];
        // a.uf.init();
        // rep(j,w)a.black[j] = (((ppp>>j)&1) == 1);
        // rep(j,w-1)if((!a.black[j]) && (!a.black[j+1]))goto Next3;
        // rep(j,w-1)if(a.black[j] && a.black[j+1])a.uf.unit(j,j+1);
        rep(j, w) if ((!a.black[j]) && (!id_[i].black[j])) goto Next3;
        rep(j, w) {
          if (c[x + 1][j] == '#' && (!a.black[j]))
            goto Next3;
          if (c[x + 1][j] == '.' && a.black[j])
            goto Next3;
        }
        /*rep(j,w)for(int k = j+1 ; k < w ; k ++)if(a.black[j] &&
        id_[i].black[j] && a.black[k] && id_[i].black[k]){ if(a.uf.same(j,k) &&
        id_[i].uf.same(j,k))goto Next3;
        }*/
        uf.init();
        rep(j, w) used[j] = false;
        rep(j, w) {
          if (a.black[j] && id_[i].black[j] && !used[a.uf.find(j)]) {
            for (int k = j + 1; k < w; k++) {
              if (a.black[k]) {
                if (a.uf.same(j, k)) {
                  if (uf.same(id_[i].uf.find(j), id_[i].uf.find(k)))
                    goto Next3;
                  else
                    uf.unit(id_[i].uf.find(j), id_[i].uf.find(k));
                }
              } else
                break;
            }
            used[a.uf.find(j)] = true;
          }
        }
        rep(j, w) {
          if (a.black[j] && id_[i].black[j]) {
            for (int k = j + 1; k < w; k++)
              if (a.black[k] && id_[i].black[k]) {
                if (id_[i].uf.same(j, k))
                  a.uf.unit(j, k);
              }
          }
        }
        // A cop = id_[i];
        if (!(w == 1 && x == h - 2)) {
          rep(j, w) if (a.black[j] && cop.black[j]) cop.uf.unit(j, 11);
          rep(j, w) if (cop.black[j] && (!cop.uf.same(j, 11))) goto Next3;
        }

        /*printf("DEBUG");
        rep(j,w)printf("%d ",a.black[j]?1:0);
        puts("");
        rep(j,w){
                rep(k,w){
                        printf("%d ",a.uf.same(j,k)?1:0);
                }
                puts("");
        }*/

        if (dp[t_][id[a].fr] < dp[t][i] + id[a].sc)
          pre[x + 1][id[a].fr] = i;
        dp[t_][id[a].fr] = max(dp[t_][id[a].fr], dp[t][i] + id[a].sc);
      Next3:;
      }
    }
    /*rep(i,s){
            printf("%d:%d\\n",i,dp[t_][i]);
    }puts("");*/
    swap(t, t_);
  }

  int ret = -1, ppp = -1;
  rep(i, s) {
    if (dp[t][i] == -INF)
      continue;
    rep(j, w) for (int k = j + 1; k < w; k++) {
      if (id_[i].black[j] && id_[i].black[k] && (!id_[i].uf.same(j, k)))
        goto Next4;
    }
    if (ret < dp[t][i])
      ppp = i;
    ret = max(ret, dp[t][i]);
  Next4:;
  }
  int loc = ppp;
  /*cout << ppp << endl;
  rrep(i,h){
          rep(j,w){
                  printf("%d",id_[ppp].black[j]?1:0);
          }
          puts("");
          ppp = pre[i][ppp];
  }
  ppp = loc;
  rrep(i,h){
          rep(j,w){
                  rep(k,w){
                          printf("%d ",id_[ppp].uf.same(j,k)?1:0);
                  }
                  puts("");
          }
          puts("");
          ppp = pre[i][ppp];
  }*/
  cout << ret << endl;
}
/*	rep(j,w){
                if(c[i][j] == '#' && (!id_[i].black[j]))goto Next2;
                if(c[i][j] == '.' && id_[i].black[j])goto Next2;
        }
        rep(j,w-1){
                if(id_[i].black[j] && id_[i].black[j+1] &&
!id_[i].uf.same(j,j+1))goto Next2;
        }
        dp[0][i] = cnt;
        goto Next2:;
}*/

//}