您的位置:首页 > 其它

[BZOJ2435] [Noi2011]道路修建

2015-10-10 23:34 316 查看

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=2435

题目大意

给定一棵树,对于每一条边,对于答案的贡献为边长*abs(所连两点两边的点数差)

题解

任取个点转成有根树,BFS一次,得到每个点自己和子节点的个数和,我们知道,对于每条边所连两个点,一定是父节点和子节点,所以子节点下面的节点数一定比父节点少,知道子节点数a,剩下的点数就是n-a,然后计算即可

var
w:array[0..3000000,1..3]of longint;
x,y:array[0..1000000]of longint;
t:array[0..1000000,1..2]of longint;
z:array[0..1000000,1..3]of longint;
i,j,k:longint;
n,len,tail,tt:longint;
a,b,c:longint;
ans:int64;
procedure init(a,b,c:longint);
begin
w[len,1]:=b; w[len,2]:=c;
if w[a,3]=0
then w[a,3]:=len else w[w[a,1],3]:=len;
w[a,1]:=len; inc(len);
end;

begin
readln(n); len:=n+1; ans:=0;
for i:=1 to n-1 do
begin readln(a,b,c); init(a,b,c); init(b,a,c); z[i,1]:=a; z[i,2]:=b; z[i,3]:=c; end;
fillchar(y,sizeof(y),0);
t[1,1]:=1; t[1,2]:=0; tail:=1; y[1]:=1;
for i:=1 to n do
begin
tt:=w[t[i,1],3];
while tt<>0 do
begin
if y[w[tt,1]]=0
then begin inc(tail); t[tail,1]:=w[tt,1]; t[tail,2]:=t[i,1]; y[w[tt,1]]:=1; end;
tt:=w[tt,3];
end;
end;
for i:=1 to n do
x[i]:=1;
for i:=n downto 1 do
inc(x[t[i,2]],x[t[i,1]]);
for i:=1 to n-1 do
begin
a:=z[i,1]; b:=z[i,2]; c:=z[i,3];
if x[a]<x[b] then j:=x[a] else j:=x[b];
k:=n-j; a:=abs(k-j);
inc(ans,int64(a)*int64(c));
end;
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: