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

#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int S = 100010;

struct UnionFind {
  vector<int> node;
  vector<ll> weight;
  UnionFind() : node(S, -1), weight(S, 0) {}
  void unite(int u, int v, ll w) {
    int ov = v, ou = u;
    u = find(u), v = find(v);
    int wa = weight[ov], wb = weight[ou];
    if (u == v)
      return;

    // (v テ」ツ?ョティツヲツェ) テ」ツつ?(u テ」ツ?ョティツヲツェ)
    // テ」ツ?ォテ」ツ?、テ」ツ?ェテ」ツ?津」ツつ?
    node[u] += node[v];
    node[v] = u;
    weight[v] += w + wb - wa;
  }

  ll get_weight(int u) {
    ll ret = 0;
    while (node[u] >= 0) {
      ret += weight[u];
      u = node[u];
    }
    return ret;
  }

  int find(int u) {
    if (node[u] < 0)
      return u;
    int par = node[u], root = find(node[u]);
    weight[u] += weight[par];
    return node[u] = root;
  }
};

int main() {
  int N, M;
  while (cin >> N >> M, N) {
    UnionFind uf;
    for (int i = 0; i < M; i++) {
      char c;
      cin >> c;
      if (c == '!') {
        int a, b, d;
        cin >> a >> b >> d;
        a--;
        b--;
        uf.unite(a, b, d);
      } else {
        int a, b;
        cin >> a >> b;
        a--;
        b--;
        if (uf.find(a) != uf.find(b))
          cout << "UNKNOWN" << endl;
        else {
          ll wa = uf.get_weight(a);
          ll wb = uf.get_weight(b);
          // printf("wa = %d, wb = %d\\n", wa, wb);
          cout << wb - wa << endl;
        }
      }
    }

    /*
    for(int i=0; i<N; i++) {
      printf("%d: parent = %d, weight = %lld, value = %lld\\n", i, uf.node[i],
    uf.weight[i], uf.get_weight(i));
    }
    */
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int S = 100010;

struct UnionFind {
  vector<int> node;
  vector<ll> weight;
  UnionFind() : node(S, -1), weight(S, 0) {}
  void unite(int u, int v, ll w) {
    if (find(u) == find(v))
      return;
    if (find(u) > find(v))
      swap(u, v), w *= -1;

    // v テ」ツ?ョティツヲツェテ」ツつ?(u テ」ツ?ョティツヲツェ)
    // テ」ツ?ォテ」ツ?、テ」ツ?ェテ」ツ?津」ツつ?
    ll prev_weight = get_weight(u);
    u = find(u);
    node[u] += node[v];
    node[v] = u;
    weight[v] += prev_weight + w;
  }

  ll get_weight(int u) {
    ll ret = 0;
    while (node[u] >= 0) {
      ret += weight[u];
      u = node[u];
    }
    return ret;
  }

  int find(int u) {
    if (node[u] < 0)
      return u;
    int par = node[u], root = find(node[u]);
    weight[u] += weight[par];
    return node[u] = root;
  }
};

int main() {
  int N, M;
  while (cin >> N >> M, N) {
    UnionFind uf;
    for (int i = 0; i < M; i++) {
      char c;
      cin >> c;
      if (c == '!') {
        int a, b, d;
        cin >> a >> b >> d;
        a--;
        b--;
        uf.unite(a, b, d);
      } else {
        int a, b;
        cin >> a >> b;
        a--;
        b--;
        if (uf.find(a) != uf.find(b))
          cout << "UNKNOWN" << endl;
        else {
          ll wa = uf.get_weight(a);
          ll wb = uf.get_weight(b);
          // printf("wa = %d, wb = %d\\n", wa, wb);
          cout << wb - wa << endl;
        }
      }
    }

    /*
    for(int i=0; i<N; i++) {
      printf("%d: parent = %d, weight = %lld, value = %lld\\n", i, uf.node[i],
    uf.weight[i], uf.get_weight(i));
    }
    */
  }
  return 0;
}