Problem p01498 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/
struct union_find {
  vector<int> par;
  union_find(int n) { REP(i, n) par.push_back(i); }
  int find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    par[y] = x;
    if (find(x) != find(y))
      par[find(y)] = x;
  }
  int count() {
    int cnt = 0;
    REP(i, par.size()) if (par[i] == i) cnt++;
    return cnt;
  }
  bool same(int x, int y) { return find(x) == find(y); }
};

int main() {
  int n, w, h;
  cin >> n >> w >> h;
  vector<vi> x(h), y(w);
  union_find uf(n);
  REP(i, n) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    x[a].push_back(i), y[b].push_back(i);
  }
  REP(i, h) REP(j, x[i].size() - 1) uf.unite(x[i][j], x[i][j + 1]);
  REP(i, w) REP(j, y[i].size() - 1) uf.unite(y[i][j], y[i][j + 1]);
  ll cnt = uf.count();
  ll ans = n - cnt;
  if (cnt > 1) {
    ans += cnt;
    ans += cnt - 1;
    if (x[0].size() || x[h - 1].size() || y[0].size() || y[w - 1].size())
      ans--;
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/
struct union_find {
  vector<int> par;
  union_find(int n) { REP(i, n) par.push_back(i); }
  int find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    par[y] = x;
    if (find(x) != find(y))
      par[find(y)] = x;
  }
  int count() {
    int cnt = 0;
    REP(i, par.size()) if (par[i] == i) cnt++;
    return cnt;
  }
  bool same(int x, int y) { return find(x) == find(y); }
};

int main() {
  int n, w, h;
  cin >> n >> w >> h;
  vector<vi> x(h), y(w);
  union_find uf(n);
  REP(i, n) {
    int a, b;
    cin >> b >> a;
    a--;
    b--;
    x[a].push_back(i), y[b].push_back(i);
  }
  REP(i, h) REP(j, x[i].size() - 1) uf.unite(x[i][j], x[i][j + 1]);
  REP(i, w) REP(j, y[i].size() - 1) uf.unite(y[i][j], y[i][j + 1]);
  ll cnt = uf.count();
  ll ans = n - cnt;
  if (cnt > 1) {
    ans += cnt;
    ans += cnt - 1;
    if (x[0].size() || x[h - 1].size() || y[0].size() || y[w - 1].size())
      ans--;
  }
  cout << ans << endl;
  return 0;
}