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

#include <cstring>
#include <iostream>
using namespace std;

int n, p[101], q[101], r[101], b[101];
bool flg[101]; // 上からつるされているかのフラグ

// 最大公約数
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }

// 最小公倍数
int lcm(int a, int b) { return a / gcd(a, b) * b; }

int solve(int idx) {
  int res = 0;

  int rcost = r[idx] ? solve(r[idx]) : 1;
  int bcost = b[idx] ? solve(b[idx]) : 1;
  int l = lcm(p[idx] * rcost, q[idx] * bcost);

  return l / p[idx] + l / q[idx];
}

int main(void) {
  while (cin >> n, n) {
    memset(flg, 0, sizeof(flg));
    for (int i = 1; i <= n; i++) {
      cin >> p[i] >> q[i] >> r[i] >> b[i];
      flg[r[i]] = flg[b[i]] = true; // 上からつるされている棒をtrueにする
    }

    for (int i = 1; i <= n; i++) {
      // 上からつるされていない棒ならば, ルートノード
      if (!flg[i]) {
        cout << solve(i) << endl;
        break;
      }
    }
  }

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
const double EPS = 1e-9;
typedef vector<int> vint;
typedef pair<int, int> pint;
#define rep(i, n) REP(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define MSG(a) cout << #a << " " << a << endl;
#define REP(i, x, n) for (int i = x; i < n; i++)
template <class T> T RoundOff(T a) { return int(a + .5 - (a < 0)); }
template <class T, class C> void chmax(T &a, C b) {
  if (a < b)
    a = b;
}
template <class T, class C> void chmin(T &a, C b) {
  if (b < a)
    a = b;
}
template <class T, class C> pair<T, C> mp(T a, C b) { return make_pair(a, b); }

ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }

ll lcm(ll x, ll y) { return x * y / gcd(x, y); }

class Q {
public:
  ll d, n;

  Q() : d(0), n(0) {}
  Q(int d, int n) : d(d), n(n) {}

  Q operator+(Q x) {
    if (d == 0 || n == 0)
      return x;
    if (x.d == 0 || x.n == 0)
      return *this;
    return Q(d * x.n + n * x.d, n * x.n).reduce();
  }

  Q operator-(Q x) {
    if (d == 0 || n == 0)
      return x;
    if (x.d == 0 || x.n == 0)
      return *this;
    return Q(d * x.n - n * x.d, n * x.n).reduce();
  }

  Q operator*(int x) { return Q(d * x, n).reduce(); }

  Q operator/(int x) { return Q(d, n * x).reduce(); }

  Q operator+=(Q x) { return (*this) = (*this) + x; }

  Q operator-=(Q x) { return (*this) = (*this) - x; }

  Q reduce() {
    if (d == 0 || n == 0)
      return Q(0, 0);

    ll gd = gcd(d, n);

    return Q(d / gd, n / gd);
  }

  Q reciprocal() { return Q(n, d); }
};

vector<Q> ans;
struct Mobile {
  int p, q, r, b;

  void divid(vector<Mobile> &mobiles, Q x) {
    Q rw = x * p / (p + q), bw = x * q / (p + q);

    if (r == 0)
      ans.push_back(rw);
    else
      mobiles[r - 1].divid(mobiles, rw);

    if (b == 0)
      ans.push_back(bw);
    else
      mobiles[b - 1].divid(mobiles, bw);
  }
};

int main() {
  int n;
  while (cin >> n && n) {
    vector<Mobile> mobiles(n);
    vector<bool> flags(n, false);

    rep(i, n) {
      cin >> mobiles[i].p >> mobiles[i].q >> mobiles[i].r >> mobiles[i].b;

      if (mobiles[i].r != 0)
        flags[mobiles[i].r - 1] = true;
      if (mobiles[i].b != 0)
        flags[mobiles[i].b - 1] = true;
    }

    ans.clear();
    mobiles[min_element(ALL(flags)) - flags.begin()].divid(mobiles, Q(1, 1));

    ll lm = ans[0].n, res = 0;

    REP(i, 1, ans.size()) lm = lcm(lm, ans[i].n);

    rep(i, ans.size()) res += (ans[i] * lm).d;

    cout << res << endl;
  }
}