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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;

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

struct node {
  vector<int> next;
  vector<pair<int, int>> blocks;
  double gx;
  double left;
  double right;
  int num;
  double weight;
  bool fl;
};

void calc(vector<vector<int>> vec, vector<pair<int, int>> piece,
          map<pair<int, int>, int> mp, node &kubo, vector<node> &nodes) {
  if (kubo.fl == 1)
    return;
  vector<int> interval;
  for (int k = 0; k < 4; k++) {
    if (piece[k].first < h - 1) {
      if (vec[piece[k].first][piece[k].second] !=
              vec[piece[k].first + 1][piece[k].second] &&
          vec[piece[k].first + 1][piece[k].second] != 0) {
        interval.push_back(piece[k].second);
      }
    }
  }
  set<int> st;
  vector<int> ne;
  for (int k = 0; k < 4; k++) {
    if (piece[k].first > 0) {
      if (vec[piece[k].first][piece[k].second] !=
              vec[piece[k].first - 1][piece[k].second] &&
          vec[piece[k].first - 1][piece[k].second] != 0) {
        if (!st.count(mp[make_pair(piece[k].first - 1, piece[k].second)])) {
          ne.push_back(mp[make_pair(piece[k].first - 1, piece[k].second)]);
          st.insert(mp[make_pair(piece[k].first - 1, piece[k].second)]);
        }
      }
    }
  }
  kubo.next = ne;
  if (interval.size() > 0) {
    sort(interval.begin(), interval.end());
  } else {
    for (int k = 0; k < w; k++) {
      if (vec[h - 1][k] != 0) {
        interval.push_back(k);
      }
    }
    sort(interval.begin(), interval.end());
  }
  kubo.left = interval[0] - 0.5;
  kubo.right = interval[interval.size() - 1] + 0.5;
  double sum = 0;
  double sum_w = 0;
  if (kubo.next.size() == 0) {
    for (int k = 0; k < 4; k++) {
      sum += (double)piece[k].second;
      sum_w += 1;
    }
    kubo.weight = sum_w;
    kubo.gx = sum / sum_w;
    kubo.fl = 1;
    return;
  }
  for (int k = 0; k < kubo.next.size(); k++) {
    calc(vec, nodes[kubo.next[k]].blocks, mp, nodes[kubo.next[k]], nodes);
    sum += nodes[kubo.next[k]].weight * nodes[kubo.next[k]].gx;
    sum_w += nodes[kubo.next[k]].weight;
  }
  for (int k = 0; k < 4; k++) {
    sum += (double)piece[k].second;
    sum_w += 1;
  }
  kubo.weight = sum_w;
  kubo.gx = sum / sum_w;
  kubo.fl = 1;
  return;
}

int main() {
  string s;
  while (1) {
    cin >> w >> h;
    if (w == 0 && h == 0)
      break;
    vector<vector<int>> vec;
    for (int i = 0; i < h; i++) {
      cin >> s;
      vector<int> vec1;
      for (int j = 0; j < w; j++) {
        if (s[j] == '.') {
          vec1.push_back(0);
        } else {
          vec1.push_back(s[j] - '0');
        }
      }
      vec.push_back(vec1);
    }
    vector<vector<int>> flag(h, vector<int>(w, 0));
    vector<node> nodes;
    int node_num = 0;
    map<pair<int, int>, int> mp;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (vec[i][j] != 0 && flag[i][j] != 1) {
          vector<pair<int, int>> piece;
          queue<pair<int, int>> q;
          q.push(make_pair(i, j));
          piece.push_back(make_pair(i, j));
          flag[i][j] = 1;
          mp[make_pair(i, j)] = node_num;
          while (!q.empty()) {
            pair<int, int> p;
            p = q.front();
            q.pop();
            for (int k = 0; k < 4; k++) {
              if (p.first + dx[k] < 0 || p.first + dx[k] >= h ||
                  p.second + dy[k] < 0 || p.second + dy[k] >= w)
                continue;
              if (flag[p.first + dx[k]][p.second + dy[k]] == 0 &&
                  vec[p.first + dx[k]][p.second + dy[k]] ==
                      vec[p.first][p.second]) {
                q.push(make_pair(p.first + dx[k], p.second + dy[k]));
                flag[p.first + dx[k]][p.second + dy[k]] = 1;
                mp[make_pair(p.first + dx[k], p.second + dy[k])] = node_num;
                piece.push_back(make_pair(p.first + dx[k], p.second + dy[k]));
              }
            }
          }
          node kubo;
          kubo.blocks = piece;
          kubo.num = node_num;
          kubo.fl = 0;
          nodes.push_back(kubo);
          node_num += 1;
        }
      }
    }
    for (int i = 0; i < nodes.size(); i++) {
      calc(vec, nodes[i].blocks, mp, nodes[i], nodes);
    }
    bool ans = 0;
    for (int i = 0; i < nodes.size(); i++) {
      if (nodes[i].gx >= nodes[i].right || nodes[i].gx <= nodes[i].left) {
        ans = 1;
      }
    }
    if (ans == 0)
      cout << "STABLE" << endl;
    else
      cout << "UNSTABLE" << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;

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

struct node {
  vector<int> next;
  vector<pair<int, int>> blocks;
  double gx;
  double left;
  double right;
  int num;
  double weight;
  bool fl;
};

void calc(vector<vector<int>> vec, vector<pair<int, int>> piece,
          map<pair<int, int>, int> mp, node &kubo, vector<node> &nodes) {
  if (kubo.fl == 1)
    return;
  vector<int> interval;
  for (int k = 0; k < 4; k++) {
    if (piece[k].first < h - 1) {
      if (vec[piece[k].first][piece[k].second] !=
              vec[piece[k].first + 1][piece[k].second] &&
          vec[piece[k].first + 1][piece[k].second] != 0) {
        interval.push_back(piece[k].second);
      }
    }
  }
  set<int> st;
  vector<int> ne;
  for (int k = 0; k < 4; k++) {
    if (piece[k].first > 0) {
      if (vec[piece[k].first][piece[k].second] !=
              vec[piece[k].first - 1][piece[k].second] &&
          vec[piece[k].first - 1][piece[k].second] != 0) {
        if (!st.count(mp[make_pair(piece[k].first - 1, piece[k].second)])) {
          ne.push_back(mp[make_pair(piece[k].first - 1, piece[k].second)]);
          st.insert(mp[make_pair(piece[k].first - 1, piece[k].second)]);
        }
      }
    }
  }
  kubo.next = ne;
  if (interval.size() > 0) {
    sort(interval.begin(), interval.end());
  } else {
    for (int k = 0; k < w; k++) {
      if (vec[h - 1][k] != 0) {
        interval.push_back(k);
      }
    }
    sort(interval.begin(), interval.end());
  }
  kubo.left = interval[0] - 0.5;
  kubo.right = interval[interval.size() - 1] + 0.5;
  double sum = 0;
  double sum_w = 0;
  if (kubo.next.size() == 0) {
    for (int k = 0; k < 4; k++) {
      sum += (double)piece[k].second;
      sum_w += 1;
    }
    kubo.weight = sum_w;
    kubo.gx = sum / sum_w;
    kubo.fl = 1;
    return;
  }
  for (int k = 0; k < kubo.next.size(); k++) {
    calc(vec, nodes[k].blocks, mp, nodes[k], nodes);
    sum += nodes[kubo.next[k]].weight * nodes[kubo.next[k]].gx;
    sum_w += nodes[kubo.next[k]].weight;
  }
  for (int k = 0; k < 4; k++) {
    sum += (double)piece[k].second;
    sum_w += 1;
  }
  kubo.weight = sum_w;
  kubo.gx = sum / sum_w;
  kubo.fl = 1;
  return;
}

int main() {
  string s;
  while (1) {
    cin >> w >> h;
    if (w == 0 && h == 0)
      break;
    vector<vector<int>> vec;
    for (int i = 0; i < h; i++) {
      cin >> s;
      vector<int> vec1;
      for (int j = 0; j < w; j++) {
        if (s[j] == '.') {
          vec1.push_back(0);
        } else {
          vec1.push_back(s[j] - '0');
        }
      }
      vec.push_back(vec1);
    }
    vector<vector<int>> flag(h, vector<int>(w, 0));
    vector<node> nodes;
    int node_num = 0;
    map<pair<int, int>, int> mp;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (vec[i][j] != 0 && flag[i][j] != 1) {
          vector<pair<int, int>> piece;
          queue<pair<int, int>> q;
          q.push(make_pair(i, j));
          piece.push_back(make_pair(i, j));
          flag[i][j] = 1;
          mp[make_pair(i, j)] = node_num;
          while (!q.empty()) {
            pair<int, int> p;
            p = q.front();
            q.pop();
            for (int k = 0; k < 4; k++) {
              if (p.first + dx[k] < 0 || p.first + dx[k] >= h ||
                  p.second + dy[k] < 0 || p.second + dy[k] >= w)
                continue;
              if (flag[p.first + dx[k]][p.second + dy[k]] == 0 &&
                  vec[p.first + dx[k]][p.second + dy[k]] ==
                      vec[p.first][p.second]) {
                q.push(make_pair(p.first + dx[k], p.second + dy[k]));
                flag[p.first + dx[k]][p.second + dy[k]] = 1;
                mp[make_pair(p.first + dx[k], p.second + dy[k])] = node_num;
                piece.push_back(make_pair(p.first + dx[k], p.second + dy[k]));
              }
            }
          }
          node kubo;
          kubo.blocks = piece;
          kubo.num = node_num;
          kubo.fl = 0;
          nodes.push_back(kubo);
          node_num += 1;
        }
      }
    }
    for (int i = 0; i < nodes.size(); i++) {
      calc(vec, nodes[i].blocks, mp, nodes[i], nodes);
    }
    bool ans = 0;
    for (int i = 0; i < nodes.size(); i++) {
      if (nodes[i].gx >= nodes[i].right || nodes[i].gx <= nodes[i].left) {
        ans = 1;
      }
    }
    if (ans == 0)
      cout << "STABLE" << endl;
    else
      cout << "UNSTABLE" << endl;
  }
  return 0;
}