Problem p01324 (C++) — buggy submission, verdict: Runtime Error

template <int Size = 1000000, typename WeightType = int>
class WeightedUnionFind {
  int par[Size], rank[Size], sizes[Size];
  WeightType wei[Size];

public:
  WeightedUnionFind() = default;
  WeightedUnionFind(const WeightedUnionFind &) = default;
  WeightedUnionFind(WeightedUnionFind &&) = default;
  WeightedUnionFind &operator=(const WeightedUnionFind &) = default;
  WeightedUnionFind &operator=(WeightedUnionFind &&) = default;

  WeightedUnionFind(int size) { init(size); }

  void init(int size) {
    for (int i = 0; i < size; ++i) {
      par[i] = i;
      rank[i] = 0;
      sizes[i] = 1;
      wei[i] = 0;
    }
  }

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

      wei[x] += wei[par[x]];

      return par[x] = p;
    }
  }

  WeightType weight(int x) {
    find(x);

    return wei[x];
  }

  void unite(int x, int y, WeightType w) {
    w += weight(x);
    w -= weight(y);
    x = find(x);
    y = find(y);

    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
      sizes[y] += sizes[x];
      wei[x] = -w;
    } else {
      par[y] = x;
      sizes[x] += sizes[y];
      wei[y] = w;
      if (rank[x] == rank[y])
        ++rank[x];
    }
  }

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

  int size(int x) { return sizes[find(x)]; }

  WeightType diff(int x, int y,
                  WeightType disabledVal = static_cast<WeightType>(-1)) {
    if (!same(x, y)) {
      return disabledVal;
    }

    return weight(x) - weight(y);
  }
};

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <vector>

int n;

int main() {
  while (std::cin >> n, n) {
    std::string tmp, lhs, rhs, times_raw;
    int cnt = 0;
    std::map<std::string, int> units;
    WeightedUnionFind<256> tree(n * 2);
    bool flag = true;

    for (int i = 0; i < n; ++i) {
      std::cin >> tmp >> lhs >> tmp >> times_raw >> rhs;

      if (!flag)
        continue;

      int times = std::stoi(times_raw.substr(times_raw.find("^") + 1));
      int l, r;
      if (units.count(lhs)) {
        l = units[lhs];
      } else {
        l = units[lhs] = cnt, ++cnt;
      }

      if (units.count(rhs)) {
        r = units[rhs];
      } else {
        r = units[rhs] = cnt, ++cnt;
      }
      if (tree.same(l, r)) {
        if (tree.diff(l, r) != times) {
          flag = false;
        }
      } else {
        tree.unite(r, l, times);
      }
    }

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

Error: 0

Fixed submission:

template <int Size = 1000000, typename WeightType = int>
class WeightedUnionFind {
  int par[Size], rank[Size], sizes[Size];
  WeightType wei[Size];

public:
  WeightedUnionFind() = default;
  WeightedUnionFind(const WeightedUnionFind &) = default;
  WeightedUnionFind(WeightedUnionFind &&) = default;
  WeightedUnionFind &operator=(const WeightedUnionFind &) = default;
  WeightedUnionFind &operator=(WeightedUnionFind &&) = default;

  WeightedUnionFind(int size) { init(size); }

  void init(int size) {
    for (int i = 0; i < size; ++i) {
      par[i] = i;
      rank[i] = 0;
      sizes[i] = 1;
      wei[i] = 0;
    }
  }

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

      wei[x] += wei[par[x]];

      return par[x] = p;
    }
  }

  WeightType weight(int x) {
    find(x);

    return wei[x];
  }

  void unite(int x, int y, WeightType w) {
    w += weight(x);
    w -= weight(y);
    x = find(x);
    y = find(y);

    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
      sizes[y] += sizes[x];
      wei[x] = -w;
    } else {
      par[y] = x;
      sizes[x] += sizes[y];
      wei[y] = w;
      if (rank[x] == rank[y])
        ++rank[x];
    }
  }

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

  int size(int x) { return sizes[find(x)]; }

  WeightType diff(int x, int y,
                  WeightType disabledVal = static_cast<WeightType>(-1)) {
    if (!same(x, y)) {
      return disabledVal;
    }

    return weight(x) - weight(y);
  }
};

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <vector>

int n;

int main() {
  while (std::cin >> n, n) {
    std::string tmp, lhs, rhs, times_raw;
    int cnt = 0;
    std::map<std::string, int> units;
    WeightedUnionFind<256> tree(n);
    bool flag = true;

    for (int i = 0; i < n; ++i) {
      std::cin >> tmp >> lhs >> tmp >> times_raw >> rhs;

      if (!flag)
        break;

      int times = std::stoi(times_raw.substr(times_raw.find("^") + 1));
      int l, r;
      if (units.count(lhs)) {
        l = units[lhs];
      } else {
        l = units[lhs] = cnt, ++cnt;
      }

      if (units.count(rhs)) {
        r = units[rhs];
      } else {
        r = units[rhs] = cnt, ++cnt;
      }

      if (tree.same(l, r)) {
        if (tree.diff(l, r) != times) {
          flag = false;
        }
      } else {
        tree.unite(r, l, times);
      }
    }

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