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 <bits/stdc++.h>
using namespace std;
const int INF = 1 << 30;

int W, H;
char mas[20][20];
int sy, sx, gy, gx;
int cnt;
int snow[144];
int number[20][20];
bool used[20][20];
const int dy[] = {0, 1, 0, -1}, dx[] = {1, 0, -1, 0};
int ans;

int dfs(int x, int y, const int &idx) {
  if (x < 0 || x >= W || y < 0 || y >= H)
    return 0;
  if (mas[y][x] != 'X')
    return 0;
  if (number[y][x] != -1)
    return 0;
  number[y][x] = idx;
  int ret = 1;
  for (int i = 0; i < 4; i++) {
    ret += dfs(x + dx[i], y + dy[i], idx);
  }
  return ret;
}
void dfs2(int x, int y, int cost, int prevx, int prevy) {
  if (ans <= cost + abs(y - gy) + abs(x - gx))
    return;
  if (y == gy && x == gx) {
    ans = min(ans, cost);
    return;
  }
  for (int i = 0; i < 4; i++) {
    int ny = y + dy[i], nx = x + dx[i];
    if (ny < 0 || ny >= H || nx < 0 || nx >= W)
      continue;
    if (used[ny][nx] && ny != prevy && nx != prevx)
      return;
  }

  for (int i = 0; i < 4; i++) {
    int ny = y + dy[i], nx = x + dx[i];
    if (ny < 0 || ny >= H || nx < 0 || nx >= W)
      continue;
    if (mas[ny][nx] == '#' || used[ny][nx])
      continue;
    if (mas[ny][nx] == 'X') {
      if (snow[number[ny][nx]] > 0)
        snow[number[ny][nx]]--;
      else
        continue;
    }
    used[ny][nx] = true;
    dfs2(nx, ny, cost + 1, x, y);
    used[ny][nx] = false;
    if (mas[ny][nx] == 'X')
      snow[number[ny][nx]]++;
  }
  return;
}

int main() {
  while (cin >> W >> H, W) {
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> mas[i][j];
        if (mas[i][j] == 'S' || mas[i][j] == 'G') {
          if (mas[i][j] == 'S')
            sy = i, sx = j;
          else
            gy = i, gx = j;
          mas[i][j] = '.';
        }
      }
    }
    cnt = 0;
    memset(number, -1, sizeof number);
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        if (mas[i][j] == 'X' && number[i][j] == -1) {
          snow[cnt] = dfs(j, i, cnt) / 2;
          cnt++;
        }
      }
    }
    memset(used, false, sizeof used);
    ans = INF;
    used[sy][sx] = true;
    dfs2(sx, sy, 0, sx, sy);
    cout << ans << endl;
  }
}