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

#include <algorithm>
#include <iostream>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)

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

int belong[14][14];
int ok[10000];
int gx, gy;

int ans = 0;
int ccc = 0;
int dfs(int x, int y, int C, int px, int py) {
  if (c[y][x] == '#' || c[y][x] == '*')
    return 0;
  if (C + abs(x - gx) + abs(y - gy) >= ans)
    return 0;
  if (c[y][x] == 'G') {
    ans = C;
    return 0;
  }
  for (int i = 0; i < 4; i++) {
    int tx = x + dx[i];
    int ty = y + dy[i];
    if (px == tx && ty == py)
      continue;
    if (c[ty][tx] == '*')
      return 0;
  }
  char cur = c[y][x];
  c[y][x] = '*';
  for (int i = 0; i < 4; i++) {
    int tx = x + dx[i];
    int ty = y + dy[i];
    if (c[ty][tx] == 'X') {
      int b = belong[ty][tx];
      if (ok[b] > 0) {
        ok[b]--;
        dfs(tx, ty, C + 1, x, y);
        ok[b]++;
      }
    } else {
      dfs(tx, ty, C + 1, x, y);
    }
  }
  c[y][x] = cur;
  return 0;
}
int grouping(int x, int y, int k) {
  if (c[y][x] != 'X')
    return 0;
  if (belong[y][x] != -1)
    return 0;
  belong[y][x] = k;
  ccc++;
  for (int i = 0; i < 4; i++)
    grouping(x + dx[i], y + dy[i], k);
}

int main() {
  ios_base::sync_with_stdio(false);
  int W, H;
  while (cin >> W >> H && W) {
    rep(i, 14) rep(j, 14) belong[i][j] = -1;
    rep(i, 14) rep(j, 14) c[i][j] = '#';
    int sx, sy;
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> c[i + 1][j + 1];
        if (c[i + 1][j + 1] == 'S') {
          c[i + 1][j + 1] = '.';
          sx = j + 1, sy = i + 1;
        } else if (c[i + 1][j + 1] == 'G') {
          gx = j + 1, gy = i + 1;
        }
      }
    }
    int k = 0;
    for (int i = 1; i <= H; i++) {
      for (int j = 1; j <= W; j++) {
        if (c[i][j] == 'X' && belong[i][j] == -1) {
          ccc = 0;
          grouping(j, i, k);
          ok[k] = ccc / 2;
          k++;
        }
      }
    }
    ans = 1e7;
    dfs(sx, sy, 0, -1, -1);
    cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef pair<int, int> P;

int w, h, sy, sx, gy, gx;
string g[20];
int ice[20][20], num[200], n;
bool vis[20][20];
int dis[20][20], ans;
const int dy[] = {-1, 0, 1, 0}, dx[] = {0, 1, 0, -1};
const int INF = 1000000;

void group(int y, int x, int c) {
  num[c]++;
  ice[y][x] = c;

  rep(i, 4) {
    int ny = y + dy[i], nx = x + dx[i];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w)
      continue;
    if (ice[ny][nx] < 0 && g[ny][nx] == 'X')
      group(ny, nx, c);
  }
}

void dfs(int y, int x, int d, int py, int px) {
  // if(ans<=d + dis[y][x])return;
  if (ans <= d + abs(y - gy) + abs(x - gx))
    return;
  if (g[y][x] == 'G') {
    ans = d;
    return;
  }

  rep(i, 4) {
    int ny = y + dy[i], nx = x + dx[i];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w)
      continue;
    if (py == ny && px == nx)
      continue;
    if (vis[ny][nx])
      return;
  }

  vis[y][x] = true;
  rep(i, 4) {
    int ny = y + dy[i], nx = x + dx[i];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w)
      continue;
    if (vis[ny][nx] || g[ny][nx] == '#')
      continue;
    if (g[ny][nx] == 'X') {
      int curg = ice[ny][nx];
      num[curg]--;
      if (num[curg] >= 0)
        dfs(ny, nx, d + 1, y, x);
      num[curg]++;
    } else {
      dfs(ny, nx, d + 1, y, x);
    }
  }
  vis[y][x] = false;
  return;
}

int main() {
  std::ios::sync_with_stdio(false);
  while (cin >> w >> h, w) {
    rep(i, h) cin >> g[i];

    n = 0;
    memset(ice, -1, sizeof(ice));
    memset(num, 0, sizeof(num));

    rep(i, h) rep(j, w) {
      if (ice[i][j] < 0 && g[i][j] == 'X')
        group(i, j, n), num[n] /= 2, n++;
      if (g[i][j] == 'S')
        sy = i, sx = j;
      if (g[i][j] == 'G')
        gy = i, gx = j;
    }

    /*
     memset(dis,-1,sizeof(dis));
     dis[gy][gx] = 0;
     queue<P> q;
     q.push(P(gy,gx));

     while(q.size()){
       P p = q.front(); q.pop();
       int y = p.first, x = p.second;
       rep(i,4){
         int ny = y + dy[i], nx = x + dx[i];
         if(ny<0 || nx<0 || ny>=h || nx>=w)continue;
         if(g[ny][nx] == '#')continue;
         if(dis[ny][nx]<0){
           dis[ny][nx] = dis[y][x] + 1;
           q.push(P(ny,nx));
         }
       }
     }
     */

    memset(vis, 0, sizeof(vis));
    ans = INF;
    dfs(sy, sx, 0, -1, -1);
    cout << ans << endl;
  }
}