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

#include <algorithm>
#include <cassert>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0; i < (int)n; i++)
#define each(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); i++)
#define pb push_back
#define mp make_pair
#define all(c) c.begin(), c.end()
#define dbg(x) cerr << __LINE__ << ": " << #x << " = " << (x) << endl

typedef vector<int> vi;
typedef pair<int, int> pi;
typedef long long ll;
const int dy[] = {-1, 0, 1, 0}, dx[] = {0, -1, 0, 1};
const int inf = (int)1e9;

int h, w, sy, sx, gy, gx;
string in[100];
set<pair<vi, int>> s;

int p[200], sz[200], size[200], dist[200][200];
int root(int x) { return x == p[x] ? x : (p[x] = root(p[x])); }

int main() {

  while (cin >> w >> h, w) {
    rep(i, h) {
      cin >> in[i];
      rep(j, w) {
        if (in[i][j] == 'S')
          sy = i, sx = j;
        if (in[i][j] == 'G')
          gy = i, gx = j;
      }
    }

    rep(i, 200) p[i] = i, sz[i] = 1;
    rep(i, 200) rep(j, 200) dist[i][j] = inf;
    rep(i, h) rep(j, w) if (in[i][j] != '#') {
      rep(d, 4) {
        int y = i + dy[d], x = j + dx[d];
        if (y < 0 || y >= h || x < 0 || x >= w)
          continue;
        if (in[y][x] != '#') {
          dist[i * w + j][y * w + x] = 1;
        }
      }
    }
    rep(k, 200) rep(i, 200) rep(j, 200) dist[i][j] =
        min(dist[i][j], dist[i][k] + dist[k][j]);

    rep(i, h) rep(j, w) if (in[i][j] == 'X') {
      rep(d, 4) {
        int y = i + dy[d], x = j + dx[d];
        if (y < 0 || y >= h || x < 0 || x >= w)
          continue;
        if (in[y][x] == 'X') {
          int a = root(y * w + x), b = root(i * w + j);
          if (a != b)
            p[b] = a, sz[a] += sz[b];
        }
      }
    }
    map<int, int> of;
    rep(i, h) rep(j, w) if (in[i][j] == 'X') { of[root(i * w + j)] = 0; }
    int k = 0;
    each(i, of) {
      i->second = k++;
      size[i->second] = sz[i->first];
    }

    vi v(k);
    s.clear();
    priority_queue<pair<pi, pair<vi, int>>> q;

    q.push(mp(mp(-dist[gy * w + gx][sy * w + sx], 0), mp(v, sy * w + sx)));

    while (!q.empty()) {
      int y = q.top().second.second / w, x = q.top().second.second % w;
      int c = q.top().first.second;
      v = q.top().second.first;
      q.pop();

      if (s.count(mp(v, y * w + x)))
        continue;
      s.insert(mp(v, y * w + x));

      if (in[y][x] == 'G') {
        cout << -c << endl;
        break;
      }

      rep(d, 4) {
        int ny = y + dy[d], nx = x + dx[d];
        if (ny < 0 || ny >= h || nx < 0 || nx >= w || in[ny][nx] == '#')
          continue;
        vi nv = v;
        if (in[ny][nx] == 'X') {
          int t = of[root(ny * w + nx)];
          nv[t]++;
          if (2 * nv[t] > size[t])
            continue;
        }
        q.push(mp(mp(-dist[gy * w + gx][ny * w + nx] + c, c - 1),
                  mp(nv, ny * w + nx)));
      }
    }
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0; i < (int)n; i++)
#define each(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); i++)
#define pb push_back
#define mp make_pair
#define all(c) c.begin(), c.end()
#define dbg(x) cerr << __LINE__ << ": " << #x << " = " << (x) << endl

typedef vector<int> vi;
typedef pair<int, int> pi;
typedef long long ll;
const int inf = (int)1e9;
const double EPS = 1e-9, INF = 1e12;

const int dy[] = {-1, 0, 1, 0}, dx[] = {0, -1, 0, 1};
int p[200];
int root(int x) {
  if (p[x] < 0)
    return x;
  return p[x] = root(p[x]);
}
int h, w, dist[200][200];
char in[12][13];

int main() {
  while (cin >> w >> h, h) {
    int sy, sx, gy, gx;
    rep(i, h * w) p[i] = -1;
    rep(i, h * w) rep(j, h * w) dist[i][j] = i == j ? 0 : inf;

    rep(i, h) {
      cin >> in[i];
      rep(j, w) {
        if (in[i][j] == 'S')
          sy = i, sx = j;
        if (in[i][j] == 'G')
          gy = i, gx = j;
        if (in[i][j] == 'X')
          rep(d, 2) {
            int ny = i + dy[d], nx = j + dx[d];
            if (ny >= 0 && nx >= 0 && in[ny][nx] == 'X') {
              int a = root(i * w + j), b = root(ny * w + nx);
              if (a != b) {
                p[a] += p[b];
                p[b] = a;
              }
            }
          }
      }
    }
    rep(i, h) rep(j, w) if (in[i][j] != '#') {
      rep(d, 4) {
        int ny = i + dy[d], nx = j + dx[d];
        if (ny < 0 || ny >= h || nx < 0 || nx >= w)
          continue;
        if (in[i][j] == '#')
          continue;
        dist[i * w + j][ny * w + nx] = 1;
      }
    }
    rep(k, 200) rep(i, 200) rep(j, 200) dist[i][j] =
        min(dist[i][j], dist[i][k] + dist[k][j]);

    priority_queue<pair<pi, pair<int, vi>>> q; // cost*, cost, pos, ice
    set<pair<int, vi>> s;

    int n = 0, to[200], sz[200];
    memset(to, -1, sizeof(to));

    rep(i, h) rep(j, w) if (in[i][j] == 'X') {
      int r = root(i * w + j);
      if (to[r] < 0) {
        sz[n] = -p[r];
        to[r] = n++;
      }
    }
    q.push(mp(mp(-dist[sy * w + sx][gy * w + gx], 0), mp(sy * w + sx, vi(n))));

    while (!q.empty()) {
      vi v = q.top().second.second;
      int cost = q.top().first.second;
      int y = q.top().second.first;
      int x = y % w;
      y /= w;
      q.pop();

      if (s.count(mp(y * w + x, v)))
        continue;
      s.insert(mp(y * w + x, v));

      if (in[y][x] == 'G') {
        cout << -cost << endl;
        break;
      }

      rep(d, 4) {
        int ny = y + dy[d], nx = x + dx[d];
        if (ny < 0 || nx < 0 || ny >= h || nx >= w)
          continue;
        if (in[ny][nx] == '#')
          continue;
        vi nv = v;

        int r = root(ny * w + nx);
        if (in[ny][nx] == 'X') {
          nv[to[r]]++;
          if (sz[to[r]] < nv[to[r]] * 2)
            continue;
        }

        if (!s.count(mp(ny * w + nx, nv)))
          q.push(mp(mp(cost - dist[ny * w + nx][gy * w + gx], cost - 1),
                    mp(ny * w + nx, nv)));
      }
    }
  }
  return 0;
}