読者です 読者をやめる 読者になる 読者になる

AOJ0520 Lightest Mobile

明らかに二分木なのでメモ化再帰するだけ
lcmを求めるところで先に2つをかけていたのでオーバーフローしてずっと悩んでました そこでみすってるとは...

#include <cstdio>
using namespace std;

typedef struct stick{
	int lren, rren, sl, sr, weight; 
} STICK;

int n, tmp, top;
int depth[101];
STICK st[101];

void init(int k){
	for(int i = 0; i <= k; i++){
		depth[i] = 0;
		st[i].weight = 0;
	}
}

int gcd(int a, int b){
	if(b == 0) return a;
	return gcd(b, a % b);
}

int lcm(int c, int d){
	return c / gcd(c, d) * d;
}

int solve(int k){
	if(st[k].weight > 0){
		return st[k].weight;
	}else{
		tmp = lcm(solve(st[k].sl) * st[k].lren, solve(st[k].sr) * st[k].rren);
		return st[k].weight = tmp / st[k].lren + tmp / st[k].rren;
	}
}

int main(){
	while(scanf("%d", &n)){
		if(n == 0) break;
		init(n);
		st[0].weight = 1;
		for(int i = 1; i <= n; i++){
			scanf("%d %d %d %d", &st[i].lren, &st[i].rren, &st[i].sl, &st[i].sr);
			tmp = gcd(st[i].lren, st[i].rren);
			st[i].lren /= tmp;
			st[i].rren /= tmp;
			if(st[i].sl != 0) depth[st[i].sl]++;
			if(st[i].sr != 0) depth[st[i].sr]++;
		}
		for(int i = 1; i<= n; i++){
			if(depth[i] == 0){
				top = i;
			}
		}
		printf("%d\n", solve(top));
	}
	return 0;
}