Problem p01296 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;

struct union_find {
  vector<int> data;
  union_find(int n) : data(n, -1) {}
  int find(int a) { return data[a] < 0 ? a : data[a] = find(data[a]); }
  bool same(int a, int b) { return find(a) == find(b); }
  void unite(int a, int b) {
    a = find(a);
    b = find(b);
    if (a == b)
      return;
    if (data[a] > data[b])
      swap(a, b);
    data[a] += data[b];
    data[b] = a;
  }
};

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

int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  int n;
  while (cin >> n, n) {
    vector<int> x(n), y(n);
    vector<char> d(n);
    map<pii, pii> pos;
    for (int i = 0; i < n; i++) {
      cin >> x[i] >> y[i] >> d[i];
      pos[make_pair(x[i], y[i])] = make_pair(i, 0);
      (d[i] == 'x' ? pos[make_pair(x[i] + 1, y[i])]
                   : pos[make_pair(x[i], y[i] + 1)]) = make_pair(i, 1);
    }
    bool ok = true;
    union_find uf(n * 2);
    for (int i = 0; i < n; i++) {
      int nx = x[i], ny = y[i];
      for (int a = 0; a < 2; a++) {
        for (int j = 0; j < 4; j++) {
          int tx = nx + dx[i], ty = ny + dy[i];
          pii tp(tx, ty);
          if (pos.count(tp) && pos[tp].first != i) {
            if (a == pos[tp].second) {
              int u = i, v = pos[tp].first;
              uf.unite(u, v);
              uf.unite(n + u, n + v);
              if (uf.same(u, n + u) || uf.same(v, n + v)) {
                ok = false;
              }
            } else {
              int u = i, v = pos[tp].first;
              uf.unite(u, n + v);
              uf.unite(n + u, v);
              if (uf.same(u, n + u) || uf.same(v, n + v)) {
                ok = false;
              }
            }
          }
        }
        (d[i] == 'x' ? nx : ny) += 1;
      }
    }
    puts(ok ? "Yes" : "No");
  }
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;

struct union_find {
  vector<int> data;
  union_find(int n) : data(n, -1) {}
  int find(int a) { return data[a] < 0 ? a : data[a] = find(data[a]); }
  bool same(int a, int b) { return find(a) == find(b); }
  void unite(int a, int b) {
    a = find(a);
    b = find(b);
    if (a == b)
      return;
    if (data[a] > data[b])
      swap(a, b);
    data[a] += data[b];
    data[b] = a;
  }
};

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

int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  int n;
  while (cin >> n, n) {
    vector<int> x(n), y(n);
    vector<char> d(n);
    map<pii, pii> pos;
    for (int i = 0; i < n; i++) {
      cin >> x[i] >> y[i] >> d[i];
      pos[make_pair(x[i], y[i])] = make_pair(i, 0);
      (d[i] == 'x' ? pos[make_pair(x[i] + 1, y[i])]
                   : pos[make_pair(x[i], y[i] + 1)]) = make_pair(i, 1);
    }
    bool ok = true;
    union_find uf(n * 2);
    for (int i = 0; i < n; i++) {
      int nx = x[i], ny = y[i];
      for (int a = 0; a < 2; a++) {
        for (int j = 0; j < 4; j++) {
          int tx = nx + dx[j], ty = ny + dy[j];
          pii tp(tx, ty);
          if (pos.count(tp) && pos[tp].first != i) {
            if (a == pos[tp].second) {
              int u = i, v = pos[tp].first;
              uf.unite(u, v);
              uf.unite(n + u, n + v);
              if (uf.same(u, n + u) || uf.same(v, n + v)) {
                ok = false;
              }
            } else {
              int u = i, v = pos[tp].first;
              uf.unite(u, n + v);
              uf.unite(n + u, v);
              if (uf.same(u, n + u) || uf.same(v, n + v)) {
                ok = false;
              }
            }
          }
        }
        (d[i] == 'x' ? nx : ny) += 1;
      }
    }
    puts(ok ? "Yes" : "No");
  }
  return 0;
}