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

#include <cstdio>
#include <queue>
#include <set>
using namespace std;

typedef long long LL;

inline LL flag(int y, int x) { return 1LL << ((y - 1) * 7 + (x - 1)); }

int dy[] = {-1, 0, 1, 0};
int dx[] = {0, -1, 0, 1};

int h, w;
int c[9][9];
int lasty, lastx;
set<LL> fail;

bool tmp[9][9];

bool check_connect(LL S) {
  for (int i = 0; i < 9; ++i)
    for (int j = 0; j < 9; ++j) {
      tmp[i][j] = false;
    }

  for (int i = 1; i <= h; ++i)
    for (int j = 1; j <= w; ++j) {
      if (S & flag(i, j)) {
        tmp[i][j] = true;
      }
    }

  bool cnt = false;
  queue<int> q;
  for (int i = 1; i <= h; ++i)
    for (int j = 1; j <= w; ++j) {
      if (tmp[i][j]) {
        if (cnt)
          return false;
        cnt = true;
        tmp[i][j] = false;
        q.push(i << 4 | j);

        while (!q.empty()) {
          for (int k = 0; k < 4; ++k) {
            int y = (q.front() >> 4) + dy[k];
            int x = (q.front() & 15) + dx[k];
            if (tmp[y][x]) {
              tmp[y][x] = false;
              q.push(y << 4 | x);
            }
          }
          q.pop();
        }
      }
    }
  return true;
}

bool dfs(int y, int x, LL S) {
  LL T = S << 8 | (y << 4) | x;
  if (!fail.insert(T).second)
    return false;

  if (!check_connect(S))
    return false;

  for (int i = 0; i < 4; ++i) {
    int ny = y + dy[i], nx = x + dx[i];
    LL f = flag(ny, nx);
    if (!c[ny][nx] && (S & f)) {
      if (ny == lasty && nx == lastx) {
        if (S == f)
          return true;
      } else if (dfs(ny, nx, S ^ f)) {
        return true;
      }

      if (y == lasty && x == lastx) {
        break;
      }
    }
  }

  return false;
}

bool solve() {
  fail.clear();

  LL S = 0;
  int firsty = -1, firstx = -1;
  int cnt0 = 0;
  for (int i = 1; i <= h; ++i)
    for (int j = 1; j <= w; ++j) {
      if (!c[i][j]) {
        ++cnt0;
        S |= flag(i, j);
        if (firsty == -1) {
          firsty = i;
          firstx = j;
        }
      }
    }

  if (S == 0)
    return false;
  if (cnt0 % 2)
    return false;

  lasty = firsty;
  lastx = firstx;
  return dfs(firsty, firstx, S);
}

int main() {
  while (scanf("%d%d", &w, &h), w) {
    for (int i = 0; i < 9; ++i)
      for (int j = 0; j < 9; ++j) {
        c[i][j] = 1;
      }

    for (int i = 1; i <= h; ++i)
      for (int j = 1; j <= w; ++j) {
        scanf("%d", &c[i][j]);
      }

    puts(solve() ? "Yes" : "No");
  }
}

Error: MLE

Fixed submission:

#include <cstdio>
#include <queue>
#include <set>
using namespace std;

typedef long long LL;

inline LL flag(int y, int x) { return 1LL << ((y - 1) * 7 + (x - 1)); }

int dy[] = {-1, 0, 1, 0};
int dx[] = {0, -1, 0, 1};

int h, w;
int c[9][9];
int lasty, lastx;
set<LL> fail;

bool tmp[9][9];

bool check_connect(LL S) {
  for (int i = 0; i < 9; ++i)
    for (int j = 0; j < 9; ++j) {
      tmp[i][j] = false;
    }

  for (int i = 1; i <= h; ++i)
    for (int j = 1; j <= w; ++j) {
      if (S & flag(i, j)) {
        tmp[i][j] = true;
      }
    }

  bool cnt = false;
  queue<int> q;
  for (int i = 1; i <= h; ++i)
    for (int j = 1; j <= w; ++j) {
      if (tmp[i][j]) {
        if (cnt)
          return false;
        cnt = true;
        tmp[i][j] = false;
        q.push(i << 4 | j);

        while (!q.empty()) {
          for (int k = 0; k < 4; ++k) {
            int y = (q.front() >> 4) + dy[k];
            int x = (q.front() & 15) + dx[k];
            if (tmp[y][x]) {
              tmp[y][x] = false;
              q.push(y << 4 | x);
            }
          }
          q.pop();
        }
      }
    }
  return true;
}

bool dfs(int y, int x, LL S) {
  LL T = S << 8 | (y << 4) | x;
  if (!fail.insert(T).second)
    return false;

  if (!check_connect(S))
    return false;

  for (int i = 0; i < 4; ++i) {
    int ny = y + dy[i], nx = x + dx[i];
    LL f = flag(ny, nx);
    if (!c[ny][nx] && (S & f)) {
      if (ny == lasty && nx == lastx) {
        if (S == f)
          return true;
      } else if (dfs(ny, nx, S ^ f)) {
        return true;
      }

      if (y == lasty && x == lastx) {
        break;
      }
    }
  }

  return false;
}

bool solve() {
  fail.clear();

  LL S = 0;
  int firsty = -1, firstx = -1;
  for (int i = 1; i <= h; ++i)
    for (int j = 1; j <= w; ++j) {
      if (!c[i][j]) {
        S |= flag(i, j);
        if (firsty == -1) {
          firsty = i;
          firstx = j;
        }
      }
    }

  if (S == 0)
    return false;

  lasty = firsty;
  lastx = firstx;
  return dfs(firsty, firstx, S);
}

int main() {
  while (scanf("%d%d", &w, &h), w) {
    for (int i = 0; i < 9; ++i)
      for (int j = 0; j < 9; ++j) {
        c[i][j] = 1;
      }

    for (int i = 1; i <= h; ++i)
      for (int j = 1; j <= w; ++j) {
        scanf("%d", &c[i][j]);
      }

    puts(solve() ? "Yes" : "No");
  }
}