Problem p02931 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <array>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < n; ++i)
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define FORR(i, a, b) for (int i = a; i >= b; --i)
#define ALL(c) (c).begin(), (c).end()

typedef long long ll;
typedef vector<int> VI;
typedef vector<ll> VL;
typedef vector<double> VD;
typedef vector<VI> VVI;
typedef vector<VL> VVL;
typedef vector<VD> VVD;
typedef pair<int, int> P;
typedef pair<ll, ll> PL;

template <typename T> void chmin(T &a, T b) {
  if (a > b)
    a = b;
}
template <typename T> void chmax(T &a, T b) {
  if (a < b)
    a = b;
}

int in() {
  int x;
  scanf("%d", &x);
  return x;
}
ll lin() {
  ll x;
  scanf("%lld", &x);
  return x;
}

struct union_find {
  VI par, sz, data;

  void init(int n) {
    sz.assign(n, 1);
    data.assign(n, 1);
    par.resize(n);
    REP(i, n) par[i] = i;
  }

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

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

  void merge(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) {
      data[x] = 0;
    } else {
      sz[y] += sz[x];
      par[x] = y;
      data[y] &= data[x];
    }
  }

  bool is_tree(int x) { return data[find(x)]; }
};

int main() {
  int n, h, w;
  cin >> n >> h >> w;
  vector<pair<ll, P>> p(n);
  REP(i, n) {
    p[i].second = P(in() - 1, in() - 1);
    p[i].first = in();
  }
  sort(ALL(p));
  reverse(ALL(p));
  union_find uf;
  uf.init(h + w);
  ll ans = 0;
  for (auto tmp : p) {
    ll x = tmp.first;
    int r = tmp.second.first;
    int c = tmp.second.second;
    c += h;
    if (uf.is_tree(r) || uf.is_tree(c)) {
      ans += x;
      uf.merge(r, c);
    }
  }
  cout << ans << endl;
  return 0;
}


Fixed submission:
#include <algorithm>
#include <array>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < n; ++i)
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define FORR(i, a, b) for (int i = a; i >= b; --i)
#define ALL(c) (c).begin(), (c).end()

typedef long long ll;
typedef vector<int> VI;
typedef vector<ll> VL;
typedef vector<double> VD;
typedef vector<VI> VVI;
typedef vector<VL> VVL;
typedef vector<VD> VVD;
typedef pair<int, int> P;
typedef pair<ll, ll> PL;

template <typename T> void chmin(T &a, T b) {
  if (a > b)
    a = b;
}
template <typename T> void chmax(T &a, T b) {
  if (a < b)
    a = b;
}

int in() {
  int x;
  scanf("%d", &x);
  return x;
}
ll lin() {
  ll x;
  scanf("%lld", &x);
  return x;
}

struct union_find {
  VI par, sz, data;

  void init(int n) {
    sz.assign(n, 1);
    data.assign(n, 1);
    par.resize(n);
    REP(i, n) par[i] = i;
  }

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

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

  void merge(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) {
      data[x] = 0;
    } else {
      sz[y] += sz[x];
      par[x] = y;
      data[y] &= data[x];
    }
  }

  bool is_tree(int x) { return data[find(x)]; }
};

int main() {
  int n, h, w;
  cin >> n >> h >> w;
  vector<pair<ll, P>> p(n);
  REP(i, n) {
    p[i].second.first = in() - 1;
    p[i].second.second = in() - 1;
    p[i].first = in();
  }
  sort(ALL(p));
  reverse(ALL(p));
  union_find uf;
  uf.init(h + w);
  ll ans = 0;
  for (auto tmp : p) {
    ll x = tmp.first;
    int r = tmp.second.first;
    int c = tmp.second.second;
    c += h;
    if (uf.is_tree(r) || uf.is_tree(c)) {
      ans += x;
      uf.merge(r, c);
    }
  }
  cout << ans << endl;
  return 0;
}