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

#include <fstream>
#include <iostream>
#include <string>
using namespace std;

struct tBar {
  unsigned int rdis, bdis, r, b;
  unsigned int w;
};
tBar bar[101];
int N;

unsigned int euclid(int a, int b) {
  while (a != b) {
    if (a > b)
      a -= b;
    else
      b -= a;
  }
  return a;
}

unsigned int calcWeight(int n) {
  tBar &bn = bar[n];
  unsigned int rw = 0, bw = 0;
  if (bn.r == 0 && bn.b == 0) {
    rw = bn.bdis;
    bw = bn.rdis;
  } else if (bn.r != 0 && bn.b == 0) {
    rw = calcWeight(bn.r);
    if (bn.rdis * rw % bn.bdis == 0) {
      bw = bn.rdis * rw / bn.bdis;
    } else {
      unsigned int e = euclid(bn.rdis * rw, bn.bdis);
      bw = bn.rdis * rw / e;
      rw *= bn.bdis / e;
    }
  } else if (bn.r == 0 && bn.b != 0) {
    bw = calcWeight(bn.b);
    if (bn.bdis * bw % bn.rdis == 0) {
      rw = bn.bdis * bw / bn.rdis;
    } else {
      unsigned int e = euclid(bn.bdis * bw, bn.rdis);
      rw = bn.bdis * bw / e;
      bw *= bn.rdis / e;
    }
  } else {
    rw = calcWeight(bn.r);
    bw = calcWeight(bn.b);
  }

  while (rw * bn.rdis != bw * bn.bdis) {
    if (rw * bn.rdis > bw * bn.bdis) {
      bw += bn.b == 0 ? bn.rdis : bar[bn.b].w;
    } else {
      rw += bn.r == 0 ? bn.bdis : bar[bn.r].w;
    }
  }
  bn.w = rw + bw;
  return bn.w;
}

int findRoot(int n) {
  for (int i = 1; i <= N; i++) {
    if (bar[i].r == n || bar[i].b == n) {
      n = i;
      i = 0;
    }
  }
  return n;
}

int main() {
  int n;
  string str;
  while (1) {
    getline(cin, str);
    sscanf(str.c_str(), "%d", &n);
    if (n == 0)
      break;
    N = n;
    for (int i = 1; i <= n; i++) {
      getline(cin, str);
      int p, q, r, b;
      sscanf(str.c_str(), "%d %d %d %d", &p, &q, &r, &b);
      int e = euclid(p, q);
      bar[i].rdis = p / e;
      bar[i].bdis = q / e;
      bar[i].r = r;
      bar[i].b = b;
      bar[i].w = 0;
    }
    int root = findRoot(1);
    int sum = calcWeight(root);
    cout << sum << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <fstream>
#include <iostream>
#include <string>
using namespace std;

struct tBar {
  unsigned int rdis, bdis, r, b;
  unsigned int w;
};
tBar bar[101];
int N;

unsigned int euclid(int a, int b) {
  while (a != b) {
    if (a > b)
      a -= b;
    else
      b -= a;
  }
  return a;
}

unsigned int calcWeight(int n) {
  tBar &bn = bar[n];
  unsigned int rw = 0, bw = 0;
  if (bn.r == 0 && bn.b == 0) {
    rw = bn.bdis;
    bw = bn.rdis;
  } else if (bn.r != 0 && bn.b == 0) {
    rw = calcWeight(bn.r);
    bw = bn.rdis * rw / bn.bdis;
  } else if (bn.r == 0 && bn.b != 0) {
    bw = calcWeight(bn.b);
    rw = bn.bdis * bw / bn.rdis;
  } else {
    rw = calcWeight(bn.r);
    bw = calcWeight(bn.b);
  }

  while (rw * bn.rdis != bw * bn.bdis) {
    if (rw * bn.rdis > bw * bn.bdis) {
      bw += bn.b == 0 ? bn.rdis : bar[bn.b].w;
    } else {
      rw += bn.r == 0 ? bn.bdis : bar[bn.r].w;
    }
  }
  bn.w = rw + bw;
  return bn.w;
}

int findRoot(int n) {
  for (int i = 1; i <= N; i++) {
    if (bar[i].r == n || bar[i].b == n) {
      n = i;
      i = 0;
    }
  }
  return n;
}

int main() {
  int n;
  string str;
  //	ifstream in("input.txt");
  //	ofstream out("output.txt");
  while (1) {
    getline(cin, str);
    sscanf(str.c_str(), "%d", &n);
    if (n == 0)
      break;
    N = n;
    for (int i = 1; i <= n; i++) {
      getline(cin, str);
      int p, q, r, b;
      sscanf(str.c_str(), "%d %d %d %d", &p, &q, &r, &b);
      int e = euclid(p, q);
      bar[i].rdis = p / e;
      bar[i].bdis = q / e;
      bar[i].r = r;
      bar[i].b = b;
      bar[i].w = 0;
    }
    int root = findRoot(1);
    int sum = calcWeight(root);
    //		out << sum << endl;
    cout << sum << endl;
  }
  //	in.close();
  //	out.close();
  return 0;
}