首先初始化解为在点1的代价.
从一个点u移动到另一个点v,相当于以v为根的子树上的所有点少走dis(u,v),其余点多走dis(u,v).
dfs遍历一次就可以出解了.
/************************************************************** Problem: 1827 User: exponent Language: Pascal Result: Accepted Time:628 ms Memory:5824 kb ****************************************************************/ {$M 10000000} type edge=record v,n,w:longint; end; const maxn=100000; var e:array[0..maxn*2] of edge; h:array[0..maxn] of longint; c,s:array[0..maxn] of longint; vis:array[0..maxn] of boolean; n,i,u,v,w,cnt:longint; ans:int64; procedure add(u,v,w:longint); begin inc(cnt); e[cnt].v:=v; e[cnt].w:=w; e[cnt].n:=h[u]; h[u]:=cnt; end; procedure getsize(u,d:longint); var v,p:longint; begin vis[u]:=true; p:=h[u]; s[u]:=c[u]; ans:=ans+int64(d)*int64(c[u]); while p<>0 do begin v:=e[p].v; if not vis[v] then begin getsize(v,d+e[p].w); inc(s[u],s[v]); end; p:=e[p].n; end; end; procedure getans(u:longint; now:int64); var v,p:longint; tmp:int64; begin if now<ans then ans:=now; vis[u]:=true; p:=h[u]; while p<>0 do begin v:=e[p].v; if not vis[v] then begin tmp:=now+int64(s[1]-s[v])*int64(e[p].w)-int64(s[v])*int64(e[p].w); getans(v,tmp); end; p:=e[p].n; end; end; begin readln(n); for i:=1 to n do readln(c[i]); for i:=1 to n-1 do begin readln(u,v,w); add(u,v,w); add(v,u,w); end; getsize(1,0); fillchar(vis,sizeof(vis),0); getans(1,ans); writeln(ans); end.