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

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

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

bool ok;
int w, h;
int field[10][10];

class edge {
public:
  int x, y, num;
};

vector<edge> G[8][8];
int en;
bool isPassedEdge[500];
bool isPassedNode[10][10];
int emp;

int sx, sy;

bool passed[10][10];

vector<int> sEdge;

void searchArrivable(int x, int y) {
  passed[y][x] = true;
  for (int i = 0; i < 4; i++) {
    int ny = y + dy[i];
    int nx = x + dx[i];
    if (ny >= 0 && nx >= 0 && ny < h && nx < w) {
      if (!passed[ny][nx] && field[ny][nx] == 0 && !isPassedNode[ny][nx]) {
        searchArrivable(nx, ny);
      }
    }
  }
}

void dfs(int x, int y) {
  if (ok)
    return;
  // ¡Ìm[h©ç¼ÌÜ¾½Çè¢ÄÈ¢m[h·×ÄÉBÂ\\©Ç¤©ðTõ
  memset(passed, 0, sizeof(passed));
  searchArrivable(x, y);
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (passed[i][j] || isPassedNode[i][j] || field[i][j] == 1)
        continue;
      // àµêÂÅàBsÂ\\Èm[hª êÎ
      else
        return;
    }
  }
  // startm[hÌ¢gpGbWªSÌm[hÉB·éÜ¦É0ÉÈÁÄµÜÁ½êÍAreturn
  int cnt = 0;
  for (int i = 0; i < G[sy][sx].size(); i++) {
    if (!isPassedNode[G[sy][sx][i].y][G[sy][sx][i].x])
      cnt++;
  }
  if (cnt == 0 && emp != 0)
    return;

  // Ü¾½Çè¢Ä¢È¢ ém[h©ç½Çè¯ém[hªPÂµ©È¢ê
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (!isPassedNode[i][j] && field[i][j] == 0 && !(i == y && j == x)) {
        int cc = 0;
        for (int k = 0; k < G[i][j].size(); k++) {
          if (!isPassedNode[G[i][j][k].y][G[i][j][k].x] ||
              (G[i][j][k].y == y && G[i][j][k].x == x) ||
              (sy == G[i][j][k].y && sx == G[i][j][k].x)) {
            cc++;
          }
        }
        if (cc == 1) {
          return;
        }
      }
    }
  }

  for (int i = 0; i < G[y][x].size(); i++) {
    edge &e = G[y][x][i];
    if (!isPassedEdge[e.num]) {
      if (emp == 0 && e.x == sx && e.y == sy) {
        ok = true;
        return;
      } else if (!isPassedNode[e.y][e.x]) {
        isPassedNode[e.y][e.x] = true;
        isPassedEdge[e.num] = true;
        emp--;
        dfs(e.x, e.y);
        if (ok)
          return;
        emp++;
        isPassedNode[e.y][e.x] = false;
        isPassedEdge[e.num] = false;
      }
    }
  }
}

int main() {

  while (cin >> w >> h && !(w == 0 && h == 0)) {
    sEdge.clear();
    for (int i = 0; i < 8; i++)
      for (int j = 0; j < 8; j++)
        G[i][j].clear();
    ok = false;
    emp = 0;
    memset(isPassedEdge, 0, sizeof(isPassedEdge));
    memset(isPassedNode, 0, sizeof(isPassedNode));
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> field[i][j];
        if (field[i][j] == 0)
          emp++;
      }
    }
    en = 0;
    bool fir = true;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (field[i][j] == 1)
          continue;
        if (fir) {
          sx = j;
          sy = i;
          fir = false;
        }
        // right
        int ny = i;
        int nx = j + 1;
        if (ny >= 0 && nx >= 0 && ny < h && nx < w && field[ny][nx] == 0) {
          edge e;
          e.y = ny;
          e.x = nx;
          e.num = en;
          G[i][j].push_back(e);
          e.y = i;
          e.x = j;
          G[ny][nx].push_back(e);
          en++;
        }
        // down
        ny = i + 1;
        nx = j;
        if (ny >= 0 && nx >= 0 && ny < h && nx < w && field[ny][nx] == 0) {
          edge e;
          e.y = ny;
          e.x = nx;
          e.num = en;
          G[i][j].push_back(e);
          e.y = i;
          e.x = j;
          G[ny][nx].push_back(e);
          en++;
        }
      }
    }

    bool isFail = false;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (G[i][j].size() == 1) {
          isFail = true;
          break;
        }
      }
      if (isFail)
        break;
    }

    if (emp == 0 || isFail)
      cout << "No" << endl;
    else {
      emp--;
      isPassedNode[sy][sx] = true;
      for (int i = 0; i < G[sy][sx].size(); i++)
        sEdge.push_back(G[sy][sx][i].num);
      dfs(sx, sy);
      if (ok)
        cout << "Yes" << endl;
      else
        cout << "No" << endl;
    }
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

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

bool ok;
int w, h;
int field[10][10];

class edge {
public:
  int x, y, num;
};

vector<edge> G[8][8];
int en;
bool isPassedEdge[500];
bool isPassedNode[10][10];
int emp;

int sx, sy;

bool passed[10][10];

vector<int> sEdge;

void searchArrivable(int x, int y) {
  passed[y][x] = true;
  for (int i = 0; i < 4; i++) {
    int ny = y + dy[i];
    int nx = x + dx[i];
    if (ny >= 0 && nx >= 0 && ny < h && nx < w) {
      if (!passed[ny][nx] && field[ny][nx] == 0 && !isPassedNode[ny][nx]) {
        searchArrivable(nx, ny);
      }
    }
  }
}

void dfs(int x, int y) {
  if (ok)
    return;
  // ¡Ìm[h©ç¼ÌÜ¾½Çè¢ÄÈ¢m[h·×ÄÉBÂ\\©Ç¤©ðTõ
  memset(passed, 0, sizeof(passed));
  searchArrivable(x, y);
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (passed[i][j] || isPassedNode[i][j] || field[i][j] == 1)
        continue;
      // àµêÂÅàBsÂ\\Èm[hª êÎ
      else
        return;
    }
  }
  ////
  ///startm[hÌ¢gpGbWªSÌm[hÉB·éÜ¦É0ÉÈÁÄµÜÁ½êÍAreturn
  // int cnt=0;
  // for(int i = 0; i < G[sy][sx].size(); i++){
  //	if(!isPassedNode[G[sy][sx][i].y][G[sy][sx][i].x])
  //		cnt++;
  // }
  // if(cnt==0&&emp!=0)
  //	return;

  // Ü¾½Çè¢Ä¢È¢ ém[h©ç½Çè¯ém[hªPÂµ©È¢ê
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (!isPassedNode[i][j]) {
        int cc = 0;
        for (int k = 0; k < G[i][j].size(); k++) {
          if (!isPassedNode[G[i][j][k].y][G[i][j][k].x] ||
              (G[i][j][k].y == y && G[i][j][k].x == x)) {
            cc++;
          }
        }
        if (cc == 1) {
          return;
        }
      }
    }
  }

  for (int i = 0; i < G[y][x].size(); i++) {
    edge &e = G[y][x][i];
    if (!isPassedEdge[e.num]) {
      if (emp == 0 && e.x == sx && e.y == sy) {
        ok = true;
        return;
      } else if (!isPassedNode[e.y][e.x]) {
        isPassedNode[e.y][e.x] = true;
        isPassedEdge[e.num] = true;
        emp--;
        dfs(e.x, e.y);
        if (ok)
          return;
        emp++;
        isPassedNode[e.y][e.x] = false;
        isPassedEdge[e.num] = false;
      }
    }
  }
}

int main() {

  while (cin >> w >> h && !(w == 0 && h == 0)) {
    sEdge.clear();
    for (int i = 0; i < 8; i++)
      for (int j = 0; j < 8; j++)
        G[i][j].clear();
    ok = false;
    emp = 0;
    memset(isPassedEdge, 0, sizeof(isPassedEdge));
    memset(isPassedNode, 0, sizeof(isPassedNode));
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> field[i][j];
        if (field[i][j] == 0)
          emp++;
      }
    }
    en = 0;
    bool fir = true;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (field[i][j] == 1)
          continue;
        if (fir) {
          sx = j;
          sy = i;
          fir = false;
        }
        // right
        int ny = i;
        int nx = j + 1;
        if (ny >= 0 && nx >= 0 && ny < h && nx < w && field[ny][nx] == 0) {
          edge e;
          e.y = ny;
          e.x = nx;
          e.num = en;
          G[i][j].push_back(e);
          e.y = i;
          e.x = j;
          G[ny][nx].push_back(e);
          en++;
        }
        // down
        ny = i + 1;
        nx = j;
        if (ny >= 0 && nx >= 0 && ny < h && nx < w && field[ny][nx] == 0) {
          edge e;
          e.y = ny;
          e.x = nx;
          e.num = en;
          G[i][j].push_back(e);
          e.y = i;
          e.x = j;
          G[ny][nx].push_back(e);
          en++;
        }
      }
    }

    bool isFail = false;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (G[i][j].size() == 1) {
          isFail = true;
          break;
        }
      }
      if (isFail)
        break;
    }

    if (emp == 0 || isFail)
      cout << "No" << endl;
    else {
      emp--;
      isPassedNode[sy][sx] = true;
      for (int i = 0; i < G[sy][sx].size(); i++)
        sEdge.push_back(G[sy][sx][i].num);
      dfs(sx, sy);
      if (ok)
        cout << "Yes" << endl;
      else
        cout << "No" << endl;
    }
  }

  return 0;
}