题意/Description:
天平的两边有时不一定只能挂物品,还可以继续挂着另一个天平,现在给你一些天平的情况和他们之间的连接关系,要求使得所有天平都能平衡所需物品的总重量最轻,一个天平平衡当且仅当“左端点的重量*左端点到支点的距离=右端点的重量*右端点到支点的距离”。注意题目中的输入保证这些天平构成一个整体。
读入/Input:
第一行包含一个N(N<=100),表示天平的数量,,天平编号为1到N,接下来包含N行描述天平的情况,每行4个整数P,Q,R,B,P和Q表示横杆上支点到左边的长度与到右边的距离的比例为P:Q,R表示左边悬挂的情况,如果R=0说明悬挂的物品,否则表示左边悬挂的是天平R;B表示右边的悬挂情况,如果B=0表示右边悬挂的是物品,否则右边悬挂着天平B。
对于所有的输入,保证W*L<2^31, 其中W为最请的天平重量,而L为输入中描述左右比例时出现的最大值。
输出/Output:
输出一个整数表示使得所有天平都平衡所需最轻的物品总重量。
题解/solution:
要想一个天平平衡,首先要使得左右天平两边平衡。假设左右两边的最轻重量 分别为W1,W2,设该天平左右两边的比例为L1:L2,要想使得该天平衡,可能左边要放大倍数 X,右边要放大倍数Y,则有以下关系式: W1*X*L1=W2*L2*Y;
即X/Y=(W2*L2)/(W1*L1),要想使天平重量最小,必须把X/Y化为最简分数,所以需要求出 W2*L2和W1*L1的最大公约数P,则X=W2*L2 div P ,Y=W1*L1 div P,整个天平的重量为 W1*X+W2*Y。
代码/Code:
var
i,kk,n:longint;
o,p,l,r:array [0..101] of longint;
function gcd(x,y:longint):longint;
begin
if y=0 then gcd:=x
else gcd:=gcd(y,x mod y);
end;
function main(x:longint):longint;
var
gc,lt,rt:int64;
begin
if x=0 then exit(1) else
begin
lt:=main(l[x]);
rt:=main(r[x]);
gc:=gcd(rt*p[x],lt*o[x]);
exit(lt*(rt*p[x] div gc)+rt*(o[x]*lt div gc));
end;
end;
procedure init;
var
i:longint;
f:array [0..101] of boolean;
begin
fillchar(f,sizeof(f),false);
readln(n);
for i:=1 to n do
begin
readln(o[i],p[i],l[i],r[i]);
if l[i]<>0 then f[l[i]]:=true;
if r[i]<>0 then f[r[i]]:=true;
end;
for i:=1 to n do
if not f[i] then
begin
kk:=i;
break;
end;
end;
begin
init;
write(main(kk));
end.