bzoj 1060 贪心
设根到每个叶子节点的距离为dis,比较容易的看出来,我们需要把这颗树的所有叶子节点的值都变成其中最大的内个,我们设为max,那么对于一颗子树来说,设其中dis值最大的为x,我们需要将这个子树根节点和子树根节点的父亲节点的边的值增加max-x,这时从贪心的角度来考虑,因为不论如何,对于当前最大的这个点来说,我们都需要将他的值增加max-x,那么我们只需要让这增加的更有价值,也就是使更多需要增加的点都被增加些,那么因为不能加多,所以取得是最大的点的dis值。那么dfs一遍就行了。
反思:过程中申请变量没有赋初值。
ps:这道题的数据有问题,生成输出数据的标程没有开longlong,开的是int,会自然溢出,所以pascal如果不手动模拟c++溢出是过不了的。
/************************************************************** Problem: 1060 User: BLADEVIL Language: Pascal Result: Wrong_Answer ****************************************************************/ //By BLADEVIL var n :longint; pre, other, len :array[0..1000010] of longint; root :longint; last :array[0..500010] of longint; l :longint; ans :int64; max1, dis :array[0..500010] of longint; procedure connect(x,y,z:longint); begin inc(l); pre[l]:=last[x]; last[x]:=l; other[l]:=y; len[l]:=z; end; procedure dfs(x,fa:longint); var q, p :longint; begin q:=last[x]; max1[x]:=x; while q<>0 do begin p:=other[q]; if p=fa then begin q:=pre[q]; continue; end; dis[p]:=dis[x]+len[q]; dfs(p,x); if dis[max1[p]]>dis[max1[x]] then max1[x]:=max1[p]; q:=pre[q]; end; end; procedure make(x,fa,tmp:longint); var q, p :longint; up, use :longint; begin up:=dis[max1[root]]; use:=0; if fa<>0 then begin use:=up-tmp-dis[max1[x]]; ans:=ans+use; end; q:=last[x]; while q<>0 do begin p:=other[q]; if p=fa then begin q:=pre[q]; continue; end; make(p,x,tmp+use); q:=pre[q]; end; end; procedure init; var i :longint; x, y, z :longint; begin read(n,root); for i:=1 to n-1 do begin read(x,y,z); connect(x,y,z); connect(y,x,z); end; dfs(root,0); end; procedure main; begin make(root,0,0); writeln(ans); end; begin init; main; end.