Problem p00443 (C++) — buggy submission, verdict: Time Limit Exceeded

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

long long depth[500];
long long w[500][2];
long long x[500][2];
long long n, root, v[500], a, A, B, C;
pair<long long, long long> DEPTH[500];
long long mobile[500][2];

long long gcd(long long p, long long q) {
  long long P = p, Q = q;
  while (true) {
    if (P % Q == 0) {
      return Q;
    }
    if (Q % P == 0) {
      return P;
    }
    if (P > Q) {
      P = P % Q;
    } else {
      Q = Q % P;
    }
  }
}

int main() {
  while (true) {
    memset(depth, 0, sizeof(depth));
    memset(w, 0, sizeof(w));
    memset(x, 0, sizeof(x));
    memset(v, 0, sizeof(v));
    memset(DEPTH, 0, sizeof(DEPTH));
    memset(mobile, 0, sizeof(mobile));
    root = 0;
    n = 0;
    A = 0;
    B = 0;
    C = 0;
    a = 0;
    cin >> n;
    if (n == 0) {
      break;
    }
    for (int i = 1; i <= n; i++) {
      v[i] = 0;
    }
    for (int i = 1; i <= n; i++) {
      cin >> w[i][0] >> w[i][1] >> x[i][0] >> x[i][1];
      v[x[i][0]] = 1;
      v[x[i][1]] = 1;
      a = gcd(w[i][0], w[i][1]);
      w[i][0] /= a;
      w[i][1] /= a;
    }
    for (int i = 1; i <= n; i++) {
      if (v[i] == 0) {
        root = i;
      }
    }
    // depth.
    for (int i = 1; i <= n; i++) {
      depth[i] = 1000;
    }
    depth[root] = 0;
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        if (depth[j] != 1000) {
          depth[x[j][0]] = min(depth[x[j][0]], depth[j] + 1);
          depth[x[j][1]] = min(depth[x[j][1]], depth[j] + 1);
        }
      }
    }
    for (int i = 1; i <= n; i++) {
      DEPTH[i - 1].first = depth[i];
      DEPTH[i - 1].second = i;
    }
    sort(DEPTH, DEPTH + n);
    for (int i = n - 1; i >= 0; i--) {
      A = DEPTH[i].first;
      B = DEPTH[i].second;
      if (x[B][0] == 0 && x[B][1] == 0) {
        mobile[B][0] = w[B][1];
        mobile[B][1] = w[B][0];
      }
      if (x[B][0] == 0 && x[B][1] >= 1) {
        mobile[B][1] = mobile[x[B][1]][0] + mobile[x[B][1]][1];
        mobile[B][1] = mobile[B][1] * w[B][0] / gcd(mobile[B][1], w[B][0]);
        mobile[B][0] = mobile[B][1] * w[B][1] / w[B][0];
      }
      if (x[B][0] >= 1 && x[B][1] == 0) {
        mobile[B][0] = mobile[x[B][0]][0] + mobile[x[B][0]][1];
        mobile[B][0] = mobile[B][0] * w[B][1] / gcd(mobile[B][0], w[B][1]);
        mobile[B][1] = mobile[B][0] * w[B][0] / w[B][1];
      }
      if (x[B][0] >= 1 && x[B][1] >= 1) {
        mobile[B][0] = mobile[x[B][0]][0] + mobile[x[B][0]][1];
        mobile[B][1] = mobile[x[B][1]][0] + mobile[x[B][1]][1];
        C = mobile[B][0] * w[B][0] * mobile[B][1] * w[B][1] /
            gcd(mobile[B][0] * w[B][0], mobile[B][1] * w[B][1]);
        mobile[B][0] = C / w[B][0];
        mobile[B][1] = C / w[B][1];
      }
    }
    cout << mobile[root][0] + mobile[root][1] << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

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

int depth[500];
int w[500][2];
int x[500][2];
int n, root, v[500], a, A, B, C;
pair<int, int> DEPTH[500];
int mobile[500][2];

int gcd(int p, int q) {
  int P = p, Q = q;
  while (true) {
    if (P % Q == 0) {
      return Q;
    }
    if (Q % P == 0) {
      return P;
    }
    if (P > Q) {
      P = P % Q;
    } else {
      Q = Q % P;
    }
  }
}

int main() {
  while (true) {
    cin >> n;
    if (n == 0) {
      break;
    }
    for (int i = 1; i <= n; i++) {
      v[i] = 0;
    }
    for (int i = 1; i <= n; i++) {
      cin >> w[i][0] >> w[i][1] >> x[i][0] >> x[i][1];
      v[x[i][0]] = 1;
      v[x[i][1]] = 1;
      a = gcd(w[i][0], w[i][1]);
      w[i][0] /= a;
      w[i][1] /= a;
    }
    for (int i = 1; i <= n; i++) {
      if (v[i] == 0) {
        root = i;
      }
    }
    // depth.
    for (int i = 1; i <= n; i++) {
      depth[i] = 1000;
    }
    depth[root] = 0;
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        if (depth[j] != 1000) {
          depth[x[j][0]] = min(depth[x[j][0]], depth[j] + 1);
          depth[x[j][1]] = min(depth[x[j][1]], depth[j] + 1);
        }
      }
    }
    for (int i = 1; i <= n; i++) {
      DEPTH[i - 1].first = depth[i];
      DEPTH[i - 1].second = i;
    }
    sort(DEPTH, DEPTH + n);
    for (int i = n - 1; i >= 0; i--) {
      A = DEPTH[i].first;
      B = DEPTH[i].second;
      if (x[B][0] == 0 && x[B][1] == 0) {
        mobile[B][0] = w[B][1];
        mobile[B][1] = w[B][0];
      }
      if (x[B][0] == 0 && x[B][1] >= 1) {
        mobile[B][1] = mobile[x[B][1]][0] + mobile[x[B][1]][1];
        mobile[B][1] = mobile[B][1] * w[B][0] / gcd(mobile[B][1], w[B][0]);
        mobile[B][0] = mobile[B][1] * w[B][1] / w[B][0];
      }
      if (x[B][0] >= 1 && x[B][1] == 0) {
        mobile[B][0] = mobile[x[B][0]][0] + mobile[x[B][0]][1];
        mobile[B][0] = mobile[B][0] * w[B][1] / gcd(mobile[B][0], w[B][1]);
        mobile[B][1] = mobile[B][0] * w[B][0] / w[B][1];
      }
      if (x[B][0] >= 1 && x[B][1] >= 1) {
        mobile[B][0] = mobile[x[B][0]][0] + mobile[x[B][0]][1];
        mobile[B][1] = mobile[x[B][1]][0] + mobile[x[B][1]][1];
        C = mobile[B][0] * w[B][0] * mobile[B][1] * w[B][1] /
            gcd(mobile[B][0] * w[B][0], mobile[B][1] * w[B][1]);
        mobile[B][0] = C / w[B][0];
        mobile[B][1] = C / w[B][0];
      }
    }
    cout << mobile[root][0] + mobile[root][1] << endl;
  }
}