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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int, int> pii;
const int INF = 1 << 29;
const double PI = acos(-1);
const double EPS = 1e-8;

int w, h;
inline bool get(ll S, int y, int x) { return S >> (y * w + x) & 1; }
inline ll bit(int y, int x) { return 1LL << (y * w + x); }
inline bool valid(int y, int x) {
  return !(y < 0 || y >= h || x < 0 || x >= w);
}
inline bool ok(ll S, int y, int x) {
  if (!valid(y, x))
    return 0;
  if (get(S, y, x))
    return 0;
  return 1;
}
const int dy[] = {-1, 0, 1, 0};
const int dx[] = {0, 1, 0, -1};
int sy, sx;
ll adj[7][7];
ll hline[3][7];
ll vline[3][7];

bool dfs(ll S, int y, int x, int num) {
  // cout << y << "," << x << "," << num << endl;
  // REP(i,h) {
  //   REP(j,w) cout << get(S,i,j);
  //   cout << endl;
  // }
  if (num == 0)
    return abs(y - sy) + abs(x - sx) == 1;
  // 上下の分裂
  if ((hline[0][y] & S) == hline[0][y]) {
    if ((hline[1][y] & S) != hline[1][y] && (hline[2][y] & S) != hline[2][y])
      return 0;
  }
  // 左右の分裂
  if ((vline[0][x] & S) == vline[0][x]) {
    if ((vline[1][x] & S) != vline[1][x] && (vline[2][x] & S) != vline[2][x])
      return 0;
  }
  // スタート地点に戻れない
  if ((adj[sy][sx] & S) == adj[sy][sx])
    return 0;
  // 今のセルと隣接しているセルで袋小路になっている
  ll T = S & ~bit(sy, sx) & ~bit(y, x);
  REP(k, 4) {
    int yy = y + dy[k];
    int xx = x + dx[k];
    if (ok(S, yy, xx)) {
      if (__builtin_popcount(adj[yy][xx] & T) >= 3)
        return 0;
    }
  }
  REP(k, 4) {
    int yy = y + dy[k];
    int xx = x + dx[k];
    if (!ok(S, yy, xx))
      continue;
    if (dfs(S | bit(yy, xx), yy, xx, num - 1))
      return 1;
  }
  return 0;
}

int main() {
  while (cin >> w >> h, h || w) {
    ll S = 0;
    int num = 0;
    int d[2] = {};
    REP(i, h) REP(j, w) {
      int a;
      cin >> a;
      if (a)
        S |= bit(i, j);
      else {
        ++num;
        sy = i, sx = j;
        d[(i + j) & 1]++;
      }
    }
    if (d[0] != d[1] || num <= 3) {
      puts("No");
      continue;
    }
    memset(hline, 0, sizeof(hline));
    REP(i, h) {
      REP(j, w) hline[0][i] |= bit(i, j);
      REP(k, i) REP(j, w) hline[1][i] |= bit(k, j);
      for (int k = i + 1; k < h; ++k)
        REP(j, w) hline[2][i] |= bit(k, j);
    }
    memset(vline, 0, sizeof(vline));
    REP(j, w) {
      REP(i, h) vline[0][j] |= bit(i, j);
      REP(k, j) REP(i, h) vline[1][j] |= bit(i, k);
      for (int k = j + 1; k < w; ++k)
        REP(i, h) vline[2][j] |= bit(i, k);
    }
    memset(adj, 0, sizeof(adj));
    REP(i, h) REP(j, w) {
      REP(k, 4) {
        int ii = i + dy[k];
        int jj = j + dx[k];
        if (valid(ii, jj))
          adj[i][j] |= bit(ii, jj);
      }
    }
    S |= bit(sy, sx);
    --num;
    cout << (dfs(S, sy, sx, num) ? "Yes" : "No") << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int, int> pii;
const int INF = 1 << 29;
const double PI = acos(-1);
const double EPS = 1e-8;

int w, h;
inline bool get(ll S, int y, int x) { return S >> (y * w + x) & 1; }
inline ll bit(int y, int x) { return 1LL << (y * w + x); }
inline bool valid(int y, int x) {
  return !(y < 0 || y >= h || x < 0 || x >= w);
}
inline bool ok(ll S, int y, int x) {
  if (!valid(y, x))
    return 0;
  if (get(S, y, x))
    return 0;
  return 1;
}
const int dy[] = {-1, 0, 1, 0};
const int dx[] = {0, 1, 0, -1};
int sy, sx;
ll adj[7][7];
ll hline[3][7];
ll vline[3][7];

bool dfs(ll S, int y, int x, int num) {
  // cout << y << "," << x << "," << num << endl;
  // REP(i,h) {
  //   REP(j,w) cout << get(S,i,j);
  //   cout << endl;
  // }
  if (num == 0)
    return abs(y - sy) + abs(x - sx) == 1;
  // 上下の分裂
  if ((hline[0][y] & S) == hline[0][y]) {
    if ((hline[1][y] & S) != hline[1][y] && (hline[2][y] & S) != hline[2][y])
      return 0;
  }
  // 左右の分裂
  if ((vline[0][x] & S) == vline[0][x]) {
    if ((vline[1][x] & S) != vline[1][x] && (vline[2][x] & S) != vline[2][x])
      return 0;
  }
  // スタート地点に戻れない
  if ((adj[sy][sx] & S) == adj[sy][sx])
    return 0;
  // 今のセルと隣接しているセルで袋小路になっている
  ll T = S & ~bit(sy, sx) & ~bit(y, x);
  REP(k, 4) {
    int yy = y + dy[k];
    int xx = x + dx[k];
    if (ok(S, yy, xx)) {
      if (__builtin_popcount(adj[yy][xx] & T) >= 3)
        return 0;
    }
  }
  REP(k, 4) {
    int yy = y + dy[k];
    int xx = x + dx[k];
    if (!ok(S, yy, xx))
      continue;
    if (dfs(S | bit(yy, xx), yy, xx, num - 1))
      return 1;
  }
  return 0;
}

int main() {
  while (cin >> w >> h, h || w) {
    ll S = 0;
    int num = 0;
    REP(i, h) REP(j, w) {
      int a;
      cin >> a;
      if (a)
        S |= bit(i, j);
      else {
        ++num;
        sy = i, sx = j;
      }
    }
    if (num <= 3) {
      puts("No");
      continue;
    }
    memset(hline, 0, sizeof(hline));
    REP(i, h) {
      REP(j, w) hline[0][i] |= bit(i, j);
      REP(k, i) REP(j, w) hline[1][i] |= bit(k, j);
      for (int k = i + 1; k < h; ++k)
        REP(j, w) hline[2][i] |= bit(k, j);
    }
    memset(vline, 0, sizeof(vline));
    REP(j, w) {
      REP(i, h) vline[0][j] |= bit(i, j);
      REP(k, j) REP(i, h) vline[1][j] |= bit(i, k);
      for (int k = j + 1; k < w; ++k)
        REP(i, h) vline[2][j] |= bit(i, k);
    }
    memset(adj, 0, sizeof(adj));
    REP(i, h) REP(j, w) {
      REP(k, 4) {
        int ii = i + dy[k];
        int jj = j + dx[k];
        if (valid(ii, jj))
          adj[i][j] |= bit(ii, jj);
      }
    }
    S |= bit(sy, sx);
    --num;
    cout << (dfs(S, sy, sx, num) ? "Yes" : "No") << endl;
  }
}