2435: [Noi2011]道路修建
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1974 Solved: 550
[Submit][Status]
Description
在 W 星球上有 n 个国家。为了各自国家的经济发展,他们决定在各个国家
之间建设双向道路使得国家之间连通。但是每个国家的国王都很吝啬,他们只愿
意修建恰好 n – 1条双向道路。 每条道路的修建都要付出一定的费用, 这个费用等于道路长度乘以道路两端的国家个数之差的绝对值。例如,在下图中,虚线所示道路两端分别有 2 个、4个国家,如果该道路长度为 1,则费用为1×|2 – 4|=2。图中圆圈里的数字表示国家的编号。
由于国家的数量十分庞大,道路的建造方案有很多种,同时每种方案的修建
费用难以用人工计算,国王们决定找人设计一个软件,对于给定的建造方案,计
算出所需要的费用。请你帮助国王们设计一个这样的软件。
Input
输入的第一行包含一个整数n,表示 W 星球上的国家的数量,国家从 1到n
编号。接下来 n – 1行描述道路建设情况,其中第 i 行包含三个整数ai、bi和ci,表
示第i 条双向道路修建在 ai与bi两个国家之间,长度为ci。
Output
输出一个整数,表示修建所有道路所需要的总费用。
Sample Input
1 2 1
1 3 1
1 4 2
6 3 1
5 2 1
Sample Output
HINT
n = 1,000,000 1≤ai, bi≤n
0 ≤ci≤ 10^6
Source
题解:
没见过这么送分的
貌似2011年是我见过送分最多的年份了 day1t1 75 day2t1100 怪不得那年铜牌线 300
再加上阿狸的打字机,用kmp大概能骗到20分……
随机选择一个节点(random),将无根树转为有根树,从下向上遍历,直接更新答案和父节点的信息 just so
这个规模据说会爆栈……果然,cena爆了11个点,不过linux下应该是无压力AC吧……
代码:
const maxn=+;
type node=record
from,go,next,w:int64;
end;
var ans:int64;
e:array[..*maxn] of node;
head,s:array[..maxn] of int64;
v:array[..maxn] of boolean;
i,n,x,y,z,root,tot:longint;
procedure ins(x,y,z:longint);
begin
inc(tot);
e[tot].from:=x;e[tot].w:=z;e[tot].go:=y;e[tot].next:=head[x];head[x]:=tot;
end;
procedure insert(x,y,z:longint);
begin
ins(x,y,z);ins(y,x,z);
end;
procedure init;
begin
readln(n);
for i:= to n- do begin readln(x,y,z);insert(x,y,z);end;
end;
procedure dfs(x:longint);
var i,y:longint;
begin
s[x]:=;
v[x]:=true;
i:=head[x];
while i<> do
begin
y:=e[i].go;
if not(v[y]) then
begin
dfs(y);
inc(s[x],s[y]);
inc(ans,e[i].w*(abs(s[y]-(n-s[y]))));
end;
i:=e[i].next;
end;
inc(s[x]);
end;
procedure main;
begin
randomize;
ans:=;
root:=random(n)+;
fillchar(v,sizeof(v),false);
dfs(root);
writeln(ans);
end;
begin
assign(input,'road.in');assign(output,'road.out');
reset(input);rewrite(output);
init;
main;
close(input);close(output);
end.