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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define EACH(t, i, c) for (t::iterator i = (c).begin(); i != (c).end(); ++i)
const double EPS = 1e-10;
const double PI = acos(-1.0);

ll gcd(ll a, ll b) { return b != 0 ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

const ll WEIGHT = -1;
struct stick {
  ll r, b, p, q;
  stick(ll r, ll b, ll p, ll q) : r(r), b(b) {
    ll g = gcd(p, q);
    this->p = p / g;
    this->q = q / g;
  }
  ll getroot(ll index, vector<stick> &sticks) {
    REP(i, sticks.size()) {
      if (sticks[i].r == index || sticks[i].b == index) {
        return sticks[i].getroot(i, sticks);
      }
    }
    return index;
  }
  ll go(vector<stick> &sticks) {
    ll rw = 0, bw = 0;
    if (r != WEIGHT) {
      rw = sticks[r].go(sticks);
    } else {
      rw = 1;
    }
    if (b != WEIGHT) {
      bw = sticks[b].go(sticks);
    } else {
      bw = 1;
    }

    ll l = lcm(p * rw, q * bw);
    rw = l / p;
    bw = l / q;
    assert(rw);
    assert(bw);

    return rw + bw;
  }
};

int main() {
  ll n;
  while (cin >> n, n) {
    vector<stick> sticks;
    REP(i, n) {
      ll p, q, r, b;
      cin >> p >> q >> r >> b;
      r--;
      b--;
      sticks.push_back(stick(r, b, p, q));
    }
    ll root = sticks[0].getroot(0, sticks);
    cout << sticks[root].go(sticks) << endl;
  }
}

Error: 0
2,3,2


Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define EACH(t, i, c) for (t::iterator i = (c).begin(); i != (c).end(); ++i)
const double EPS = 1e-10;
const double PI = acos(-1.0);

ll gcd(ll a, ll b) { return b != 0 ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

const ll WEIGHT = -1;
struct stick {
  ll r, b, p, q;
  stick(ll r, ll b, ll p, ll q) : r(r), b(b) {
    ll g = gcd(p, q);
    this->p = p / g;
    this->q = q / g;
  }
  ll getroot(ll index, vector<stick> &sticks) {
    REP(i, sticks.size()) {
      if (sticks[i].r == index || sticks[i].b == index) {
        return sticks[i].getroot(i, sticks);
      }
    }
    return index;
  }
  ll go(vector<stick> &sticks) {
    ll rw = 0, bw = 0;
    if (r != WEIGHT) {
      rw = sticks[r].go(sticks);
    }
    if (b != WEIGHT) {
      bw = sticks[b].go(sticks);
    }
    if (r == WEIGHT && b == WEIGHT) {
      rw = q;
      bw = p;
      assert(rw);
      assert(bw);
    } else if (r == WEIGHT) {
      if (p * bw % q) {
        rw = bw * p;
        bw *= q;
        assert(rw);
      } else {
        rw = bw * p / q;
        assert(bw);
        cerr << bw << "," << p << "," << q << endl;
        assert(rw);
      }
      assert(rw);
      assert(bw);
    } else if (b == WEIGHT) {
      if (q * rw % p) {
        bw = rw * q;
        rw *= p;
      } else {
        bw = rw * q / p;
        assert(rw);
      }
      assert(rw);
      assert(bw);
    } else {
      ll l = lcm(p * rw, q * bw);
      rw = l / p;
      bw = l / q;
      assert(rw);
      assert(bw);
    }
    assert(rw && bw);
    return rw + bw;
  }
};

int main() {
  ll n;
  while (cin >> n, n) {
    vector<stick> sticks;
    REP(i, n) {
      ll p, q, r, b;
      cin >> p >> q >> r >> b;
      r--;
      b--;
      sticks.push_back(stick(r, b, p, q));
    }
    ll root = sticks[0].getroot(0, sticks);
    cout << sticks[root].go(sticks) << endl;
  }
}