Problem p03450 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

#define DEBUG(x) cout << #x << ": " << x << endl;
#define DEBUG_VEC(v)                                                           \
  cout << #v << ":";                                                           \
  for (int i = 0; i < v.size(); i++)                                           \
    cout << " " << v[i];                                                       \
  cout << endl

typedef long long ll;
#define vi vector<int>
#define vl vector<ll>
#define vii vector<vector<int>>
#define vll vector<vector<ll>>
#define vs vector<string>
#define pii pair<int, int>
#define pis pair<int, string>
#define psi pair<string, int>
#define pll pair<ll, ll>
#define fi first
#define se second
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(c) c.begin(), c.end()
#define in(x, a, b) a <= x &&x < b
const int inf = 1000000001;
const ll INF = 2e18;
const ll MOD = 1000000007;
// const ll mod = 1000000009;
const double pi = 3.14159265358979323846;
#define Sp(p) cout << setprecision(15) << fixed << p << endl;
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int dx2[8] = {1, 1, 0, -1, -1, -1, 0, 1}, dy2[8] = {0, 1, 1, 1, 0, -1, -1, -1};

class WeightedUF {
public:
  vi par, ran, num;
  vl diff_weight; // 親ノード(根ノードではない)との値の差分

  WeightedUF(int n) {
    par.resize(n);
    ran.resize(n);
    num.resize(n);
    diff_weight.resize(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
      ran[i] = 0;
      num[i] = 1;
      diff_weight[i] = 0;
    }
  }

  // 木の根を求める
  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      int root = find(par[x]);
      diff_weight[x] += diff_weight[par[x]];
      return par[x] = root;
    }
  }

  ll weight(int x) {
    find(x); // 経路圧縮
    return diff_weight[x];
  }

  // xからみたyの重み
  ll diff(int x, int y) {
    if (!same(x, y)) {
      return -INF;
    } else {
      return weight(y) - weight(x);
    }
  }

  // xからみたyの重みがwになるように併合
  bool unite(int x, int y, ll w) {
    w += weight(x);
    w -= weight(y);
    x = find(x);
    y = find(y);
    int numsum = num[x] + num[y];
    if (x == y) {
      if (diff(x, y) == w) {
        return true;
      } else {
        return false;
      }
    }
    if (ran[x] < ran[y]) {
      swap(x, y);
      w = -w;
    }
    par[y] = x;
    if (ran[x] == ran[y]) {
      ran[x]++;
    }
    diff_weight[y] = w;
    num[x] = num[y] = numsum;
    return true;
  }

  // xとyが同じ集合に属するか否か
  bool same(int x, int y) { return find(x) == find(y); }
};

int main() {
  int n, m;
  cin >> n >> m;
  WeightedUF uf(n);
  rep(i, m) {
    int l, r, d;
    cin >> l >> r >> d;
    if (!uf.unite(l, r, d)) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

#define DEBUG(x) cout << #x << ": " << x << endl;
#define DEBUG_VEC(v)                                                           \
  cout << #v << ":";                                                           \
  for (int i = 0; i < v.size(); i++)                                           \
    cout << " " << v[i];                                                       \
  cout << endl

typedef long long ll;
#define vi vector<int>
#define vl vector<ll>
#define vii vector<vector<int>>
#define vll vector<vector<ll>>
#define vs vector<string>
#define pii pair<int, int>
#define pis pair<int, string>
#define psi pair<string, int>
#define pll pair<ll, ll>
#define fi first
#define se second
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(c) c.begin(), c.end()
#define in(x, a, b) a <= x &&x < b
const int inf = 1000000001;
const ll INF = 2e18;
const ll MOD = 1000000007;
// const ll mod = 1000000009;
const double pi = 3.14159265358979323846;
#define Sp(p) cout << setprecision(15) << fixed << p << endl;
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int dx2[8] = {1, 1, 0, -1, -1, -1, 0, 1}, dy2[8] = {0, 1, 1, 1, 0, -1, -1, -1};

class WeightedUF {
public:
  vi par, ran, num;
  vl diff_weight; // 親ノード(根ノードではない)との値の差分

  WeightedUF(int n) {
    par.resize(n);
    ran.resize(n);
    num.resize(n);
    diff_weight.resize(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
      ran[i] = 0;
      num[i] = 1;
      diff_weight[i] = 0;
    }
  }

  // 木の根を求める
  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      int root = find(par[x]);
      diff_weight[x] += diff_weight[par[x]];
      return par[x] = root;
    }
  }

  ll weight(int x) {
    find(x); // 経路圧縮
    return diff_weight[x];
  }

  // xからみたyの重み
  ll diff(int x, int y) {
    if (!same(x, y)) {
      return -INF;
    } else {
      return weight(y) - weight(x);
    }
  }

  // xからみたyの重みがwになるように併合
  bool unite(int x, int y, ll w) {
    w += weight(x);
    w -= weight(y);
    x = find(x);
    y = find(y);
    int numsum = num[x] + num[y];
    if (x == y) {
      if (diff(x, y) == w) {
        return true;
      } else {
        return false;
      }
    }
    if (ran[x] < ran[y]) {
      swap(x, y);
      w = -w;
    }
    par[y] = x;
    if (ran[x] == ran[y]) {
      ran[x]++;
    }
    diff_weight[y] = w;
    num[x] = num[y] = numsum;
    return true;
  }

  // xとyが同じ集合に属するか否か
  bool same(int x, int y) { return find(x) == find(y); }
};

int main() {
  int n, m;
  cin >> n >> m;
  WeightedUF uf(n);
  rep(i, m) {
    int l, r, d;
    cin >> l >> r >> d;
    l--;
    r--;
    if (!uf.unite(l, r, d)) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}