Problem p03450 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define LLI long long int
#define FOR(v, a, b) for (LLI v = (a); v < (b); ++v)
#define FORE(v, a, b) for (LLI v = (a); v <= (b); ++v)
#define REP(v, n) FOR(v, 0, n)
#define REPE(v, n) FORE(v, 0, n)
#define REV(v, a, b) for (LLI v = (a); v >= (b); --v)
#define ALL(x) (x).begin(), (x).end()
#define RALL(x) (x).rbegin(), (x).rend()
#define ITR(it, c) for (auto it = (c).begin(); it != (c).end(); ++it)
#define RITR(it, c) for (auto it = (c).rbegin(); it != (c).rend(); ++it)
#define EXIST(c, x) ((c).find(x) != (c).end())
#define fst first
#define snd second
#define popcount __builtin_popcount
#define UNIQ(v) (v).erase(unique(ALL(v)), (v).end())
#define bit(i) (1LL << (i))

#ifdef DEBUG
#include <misc/C++/Debug.cpp>
#else
#define dump(...) ((void)0)
#endif

#define gcd __gcd

using namespace std;
template <class T> constexpr T lcm(T m, T n) { return m / gcd(m, n) * n; }

template <typename I> void join(ostream &ost, I s, I t, string d = " ") {
  for (auto i = s; i != t; ++i) {
    if (i != s)
      ost << d;
    ost << *i;
  }
  ost << endl;
}
template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (auto &a : v)
    is >> a;
  return is;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}

template <typename T, typename U> bool chmin(T &a, const U &b) {
  return (a > b ? a = b, true : false);
}
template <typename T, typename U> bool chmax(T &a, const U &b) {
  return (a < b ? a = b, true : false);
}
template <typename T, size_t N, typename U>
void fill_array(T (&a)[N], const U &v) {
  fill((U *)a, (U *)(a + N), v);
}

template <typename T> class WeightedUnionFind {
  vector<int> parent, depth, size;
  vector<T> weight;
  int count;

public:
  WeightedUnionFind(int n) : parent(n), depth(n, 1), size(n, 1), weight(n, 0) {
    iota(ALL(parent), 0);
  }

  int get_root(int i) {
    if (parent[i] == i)
      return i;
    else {
      int p = get_root(parent[i]);
      weight[i] += weight[parent[i]];
      return parent[i] = p;
    }
  }

  T get_weight(int i) {
    get_root(i);
    return weight[i];
  }
  bool is_same(int i, int j) { return get_root(i) == get_root(j); }
  T diff(int i, int j) { return get_weight(i) - get_weight(j); }

  int merge(int i, int j, T w) {
    int ri = get_root(i), rj = get_root(j);
    if (ri == rj)
      return ri;
    else {
      if (depth[ri] < depth[rj]) {
        parent[ri] = rj;
        size[rj] += size[ri];
        weight[ri] = w - weight[i] + weight[j];
        return rj;
      } else {
        parent[rj] = ri;
        size[ri] += size[rj];
        weight[rj] = -w + weight[i] - weight[j];
        if (depth[ri] == depth[rj])
          ++depth[ri];
        return ri;
      }
    }
  }

  int get_size(int i) { return size[get_root(i)]; }
  int count_group() { return count; }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n, m;
  while (cin >> n >> m) {
    WeightedUnionFind<int> wuf(n);
    bool ans = true;

    REP(i, m) {
      int l, r, d;
      cin >> l >> r >> d;
      --l, --r;

      if (wuf.is_same(l, r)) {
        int diff = wuf.diff(l, r);
        if (d != diff) {
          ans = false;
          break;
        }
      } else {
        wuf.merge(l, r, d);
      }
    }

    cout << (ans ? "Yes" : "No") << endl;
  }

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define LLI long long int
#define FOR(v, a, b) for (LLI v = (a); v < (b); ++v)
#define FORE(v, a, b) for (LLI v = (a); v <= (b); ++v)
#define REP(v, n) FOR(v, 0, n)
#define REPE(v, n) FORE(v, 0, n)
#define REV(v, a, b) for (LLI v = (a); v >= (b); --v)
#define ALL(x) (x).begin(), (x).end()
#define RALL(x) (x).rbegin(), (x).rend()
#define ITR(it, c) for (auto it = (c).begin(); it != (c).end(); ++it)
#define RITR(it, c) for (auto it = (c).rbegin(); it != (c).rend(); ++it)
#define EXIST(c, x) ((c).find(x) != (c).end())
#define fst first
#define snd second
#define popcount __builtin_popcount
#define UNIQ(v) (v).erase(unique(ALL(v)), (v).end())
#define bit(i) (1LL << (i))

#ifdef DEBUG
#include <misc/C++/Debug.cpp>
#else
#define dump(...) ((void)0)
#endif

#define gcd __gcd

using namespace std;
template <class T> constexpr T lcm(T m, T n) { return m / gcd(m, n) * n; }

template <typename I> void join(ostream &ost, I s, I t, string d = " ") {
  for (auto i = s; i != t; ++i) {
    if (i != s)
      ost << d;
    ost << *i;
  }
  ost << endl;
}
template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (auto &a : v)
    is >> a;
  return is;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}

template <typename T, typename U> bool chmin(T &a, const U &b) {
  return (a > b ? a = b, true : false);
}
template <typename T, typename U> bool chmax(T &a, const U &b) {
  return (a < b ? a = b, true : false);
}
template <typename T, size_t N, typename U>
void fill_array(T (&a)[N], const U &v) {
  fill((U *)a, (U *)(a + N), v);
}

template <typename T> class WeightedUnionFind {
  vector<int> parent, depth, size;
  vector<T> weight;
  int count;

public:
  WeightedUnionFind(int n) : parent(n), depth(n, 1), size(n, 1), weight(n, 0) {
    iota(ALL(parent), 0);
  }

  int get_root(int i) {
    if (parent[i] == i)
      return i;
    else {
      int p = get_root(parent[i]);
      weight[i] += weight[parent[i]];
      return parent[i] = p;
    }
  }

  T get_weight(int i) {
    get_root(i);
    return weight[i];
  }
  bool is_same(int i, int j) { return get_root(i) == get_root(j); }
  T diff(int i, int j) { return get_weight(i) - get_weight(j); }

  int merge(int i, int j, T w) {
    int ri = get_root(i), rj = get_root(j);
    if (ri == rj)
      return ri;
    else {
      if (depth[ri] < depth[rj]) {
        parent[ri] = rj;
        size[rj] += size[ri];
        weight[ri] = w - weight[i] + weight[j];
        return rj;
      } else {
        parent[rj] = ri;
        size[ri] += size[rj];
        weight[rj] = -w + weight[i] - weight[j];
        if (depth[ri] == depth[rj])
          ++depth[ri];
        return ri;
      }
    }
  }

  int get_size(int i) { return size[get_root(i)]; }
  int count_group() { return count; }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n, m;
  while (cin >> n >> m) {
    WeightedUnionFind<int> wuf(n);
    bool ans = true;

    REP(i, m) {
      int l, r, d;
      cin >> l >> r >> d;
      --l, --r;

      if (wuf.is_same(l, r)) {
        int diff = wuf.diff(l, r);
        if (d != diff) {
          ans = false;
        }
      } else {
        wuf.merge(l, r, d);
      }
    }

    cout << (ans ? "Yes" : "No") << endl;
  }

  return 0;
}