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

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define INF_LL 9000000000000000000
#define INF 2000000000

#define REP(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;
typedef pair<int, PII> PPII;
typedef pair<int, PPII> PPPII;

class Union_find {
private:
  vector<int> par;
  vector<int> rank;
  int n;

public:
  Union_find(int a) {
    n = a;
    for (int i = 0; i < n; i++) {
      par.push_back(i);
      rank.push_back(0);
    }
  }

  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }
};

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

int main(void) {
  int H, W;
  string f[2][1010];
  cin >> H >> W;
  queue<PII> que[2];
  REP(i, H) {
    cin >> f[0][i];
    REP(j, W) {
      if (f[0][i][j] != '.')
        que[0].push(PII(i, j));
    }
  }
  int cnt = 0;
  ll res = 0;
  while (1) {
    cnt = 0;
    set<PII> st;
    REP(i, 1010) { f[(res + 1) % 2][i] = f[res % 2][i]; }
    while (que[res % 2].size()) {
      PII p = que[res % 2].front();
      que[res % 2].pop();
      int sarati = 0;
      REP(i, 8) {
        if (f[res % 2][p.first + dy[i]][p.second + dx[i]] == '.')
          sarati++;
      }
      if (f[res % 2][p.first][p.second] != '.' &&
          sarati >= f[res % 2][p.first][p.second] - '0') {
        f[(res + 1) % 2][p.first][p.second] = '.';
        REP(i, 8) {
          if (f[res % 2][p.first + dy[i]][p.second + dx[i]] != '.')
            st.insert({p.first + dy[i], p.second + dx[i]});
        }
        cnt++;
      }
    }
    for (auto x : st) {
      que[(res + 1) % 2].push(x);
    }
    if (cnt == 0)
      break;
    else
      res++;
  }
  cout << res << endl;
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define INF_LL 9000000000000000000
#define INF 2000000000

#define REP(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;
typedef pair<int, PII> PPII;
typedef pair<int, PPII> PPPII;

class Union_find {
private:
  vector<int> par;
  vector<int> rank;
  int n;

public:
  Union_find(int a) {
    n = a;
    for (int i = 0; i < n; i++) {
      par.push_back(i);
      rank.push_back(0);
    }
  }

  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }
};

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

int main(void) {
  int H, W;
  string f[2][1010];
  cin >> H >> W;
  queue<PII> que[2];
  REP(i, H) {
    cin >> f[0][i];
    REP(j, W) {
      if (f[0][i][j] != '.')
        que[0].push(PII(i, j));
    }
  }
  int cnt = 0;
  ll res = 0;
  while (1) {
    cnt = 0;
    REP(i, 1010) { f[(res + 1) % 2][i] = f[res % 2][i]; }
    while (que[res % 2].size()) {
      PII p = que[res % 2].front();
      que[res % 2].pop();
      int sarati = 0;
      REP(i, 8) {
        if (f[res % 2][p.first + dy[i]][p.second + dx[i]] == '.')
          sarati++;
      }
      if (f[res % 2][p.first][p.second] != '.' &&
          sarati >= f[res % 2][p.first][p.second] - '0') {
        f[(res + 1) % 2][p.first][p.second] = '.';
        REP(i, 8) {
          if (f[res % 2][p.first + dy[i]][p.second + dx[i]] != '.')
            que[(res + 1) % 2].push({p.first + dy[i], p.second + dx[i]});
        }
        cnt++;
      }
    }
    if (cnt == 0)
      break;
    else
      res++;
  }
  cout << res << endl;
  return 0;
}