Problem p01098 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;

#define EPS (1e-7)
#define INF (1e9)
#define PI (acos(-1))
// const ll mod = 1000000007;
struct UnionFind {
  vector<int> par;
  vector<int> rank;
  vector<ll> Size;
  UnionFind(int n = 1) { init(n); }

  void init(int n = 1) {
    par.resize(n + 1);
    rank.resize(n + 1);
    Size.resize(n + 1);
    for (int i = 0; i <= n; ++i)
      par[i] = i, rank[i] = 0, Size[i] = 1;
  }

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

  bool issame(int x, int y) { return root(x) == root(y); }

  bool merge(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (rank[x] < rank[y])
      swap(x, y);
    if (rank[x] == rank[y])
      ++rank[x];
    par[y] = x;
    Size[x] += Size[y];
    return true;
  }

  ll size(int x) { return Size[root(x)]; }
};

string field[105];
string WHITE;
int dh[4] = {1, -1, 0, 0};
int dw[4] = {0, 0, 1, -1};
string tree[2];
int ROOT;
unordered_map<int, vector<int>> children;
unordered_map<int, int> parent;

string search(int from) {
  vector<string> ch;
  for (int i = 0; i < children[from].size(); i++) {
    ch.push_back(search(children[from][i]));
  }
  sort(ch.begin(), ch.end());
  string ret;
  for (int i = 0; i < ch.size(); i++) {
    ret += ch[i];
  }
  ret = "(" + ret + ")";
  return ret;
}

int main() {
  // cout.precision(10);
  cin.tie(0);
  ios::sync_with_stdio(false);
  for (int i = 0; i <= 105; i++)
    WHITE.push_back('.');
  bool end = false;
  while (true) {
    if (end)
      break;
    for (int picture = 0; picture <= 1; picture++) {
      children.clear();
      parent.clear();
      tree[picture].clear();
      int H, W;
      cin >> H >> W;
      if (H == 0) {
        end = true;
        break;
      }
      UnionFind uni(30050);
      uni.par[0] = 1;
      field[0] = WHITE;
      field[H + 1] = WHITE;
      for (int h = 1; h <= H; h++) {
        cin >> field[h];
        field[h] = "." + field[h] + ".";
      }
      for (int h = 0; h <= H + 1; h++) {
        for (int w = 0; w <= W + 1; w++) {
          if (field[h][w] == '.') {
            for (int k = 0; k <= 3; k++) {
              int newh = h + dh[k];
              int neww = w + dw[k];
              if (newh < 0 || newh > H + 1 || neww < 0 || neww > W + 1)
                continue;
              if (field[newh][neww] == '.')
                uni.merge(h * 200 + w, newh * 200 + neww);
            }
          } else {
            for (int newh = h - 1; newh <= h + 1; newh++) {
              for (int neww = w - 1; neww <= w + 1; neww++) {
                if (newh < 0 || newh > H + 1 || neww < 0 || neww > W + 1)
                  continue;
                if (field[newh][neww] == '#')
                  uni.merge(h * 200 + w, newh * 200 + neww);
              }
            }
          }
        }
      }
      for (int h = 0; h <= H + 1; h++) {
        // for(int w = 0; w <= W + 1; w++) cerr << uni.root(h * 200 + w) << " ";
        // cerr << endl;
      }
      ROOT = uni.root(0);
      parent[ROOT] = -1;
      // cerr << "ROOT: " << ROOT << endl;
      for (int h = 1; h <= H + 1; h++) {
        for (int w = 0; w <= W + 1; w++) {
          int now = uni.root(h * 200 + w);
          if (parent[now] != 0)
            continue;
          parent[now] = uni.root((h - 1) * 200 + w);
          children[parent[now]].push_back(now);
          // cerr << now << " " << parent[now] << endl;
        }
      }
      tree[picture] = search(ROOT);
    }
    if (end)
      break;
    if (tree[0] == tree[1])
      cout << "yes" << endl;
    else
      cout << "no" << endl;
  }
  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;

#define EPS (1e-7)
#define INF (1e9)
#define PI (acos(-1))
// const ll mod = 1000000007;
struct UnionFind {
  vector<int> par;
  vector<int> rank;
  vector<ll> Size;
  UnionFind(int n = 1) { init(n); }

  void init(int n = 1) {
    par.resize(n + 1);
    rank.resize(n + 1);
    Size.resize(n + 1);
    for (int i = 0; i <= n; ++i)
      par[i] = i, rank[i] = 0, Size[i] = 1;
  }

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

  bool issame(int x, int y) { return root(x) == root(y); }

  bool merge(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (rank[x] < rank[y])
      swap(x, y);
    if (rank[x] == rank[y])
      ++rank[x];
    par[y] = x;
    Size[x] += Size[y];
    return true;
  }

  ll size(int x) { return Size[root(x)]; }
};

string field[105];
string WHITE;
int dh[4] = {1, -1, 0, 0};
int dw[4] = {0, 0, 1, -1};
string tree[2];
int ROOT;
unordered_map<int, vector<int>> children;
unordered_map<int, int> parent;

string search(int from) {
  vector<string> ch;
  for (int i = 0; i < children[from].size(); i++) {
    ch.push_back(search(children[from][i]));
  }
  sort(ch.begin(), ch.end());
  string ret;
  for (int i = 0; i < ch.size(); i++) {
    ret += ch[i];
  }
  ret = "(" + ret + ")";
  return ret;
}

int main() {
  // cout.precision(10);
  cin.tie(0);
  ios::sync_with_stdio(false);
  for (int i = 0; i <= 100; i++)
    WHITE.push_back('.');
  bool end = false;
  while (true) {
    if (end)
      break;
    for (int picture = 0; picture <= 1; picture++) {
      children.clear();
      parent.clear();
      tree[picture].clear();
      int H, W;
      cin >> H >> W;
      if (H == 0) {
        end = true;
        break;
      }
      UnionFind uni(20050);
      uni.par[0] = 1;
      field[0] = WHITE;
      field[H + 1] = WHITE;
      for (int h = 1; h <= H; h++) {
        cin >> field[h];
        field[h] = "." + field[h] + ".";
      }
      for (int h = 0; h <= H + 1; h++) {
        for (int w = 0; w <= W + 1; w++) {
          if (field[h][w] == '.') {
            for (int k = 0; k <= 3; k++) {
              int newh = h + dh[k];
              int neww = w + dw[k];
              if (newh < 0 || newh > H + 1 || neww < 0 || neww > W + 1)
                continue;
              if (field[newh][neww] == '.')
                uni.merge(h * 200 + w, newh * 200 + neww);
            }
          } else {
            for (int newh = h - 1; newh <= h + 1; newh++) {
              for (int neww = w - 1; neww <= w + 1; neww++) {
                if (newh < 0 || newh > H + 1 || neww < 0 || neww > W + 1)
                  continue;
                if (field[newh][neww] == '#')
                  uni.merge(h * 200 + w, newh * 200 + neww);
              }
            }
          }
        }
      }
      for (int h = 0; h <= H + 1; h++) {
        // for(int w = 0; w <= W + 1; w++) cerr << uni.root(h * 200 + w) << " ";
        // cerr << endl;
      }
      ROOT = uni.root(0);
      parent[ROOT] = -1;
      // cerr << "ROOT: " << ROOT << endl;
      for (int h = 1; h <= H + 1; h++) {
        for (int w = 0; w <= W + 1; w++) {
          int now = uni.root(h * 200 + w);
          if (parent[now] != 0)
            continue;
          parent[now] = uni.root((h - 1) * 200 + w);
          children[parent[now]].push_back(now);
          // cerr << now << " " << parent[now] << endl;
        }
      }
      tree[picture] = search(ROOT);
    }
    if (end)
      break;
    if (tree[0] == tree[1])
      cout << "yes" << endl;
    else
      cout << "no" << endl;
  }
  return 0;
}