【题解】
无根树转有根树,记录每个点的size(以它为根的子树含有多少结点),然后再从根dfs一遍整棵树即可,每条边i的贡献是:abs( (n-size[v[i]]) - size[v[i]] ) * w[i]
【代码】
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef long long LL;
int v[2000005]={0},w[2000005]={0},first[1000005]={0},next[2000005]={0},size[1000005]={0};
LL cost[2000005]={0};
int n,e=0;
void tj(int x,int y,int z)
{
v[++e]=y;
w[e]=z;
next[e]=first[x];
first[x]=e;
}
void dfs(int x,int fa)
{
int i;
size[x]=1;
for(i=first[x];i!=0;i=next[i])
if(v[i]!=fa)
{
dfs(v[i],x);
size[x]+=size[v[i]];
}
}
void getcost(int x,int fa)
{
int i;
for(i=first[x];i!=0;i=next[i])
if(v[i]!=fa)
{
cost[i]=(LL)w[i]*(LL)abs(n-size[v[i]]*2);
getcost(v[i],x);
}
}
int main()
{
LL ans=0;
int i,x,y,z;
scanf("%d",&n);
for(i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
tj(x,y,z);
tj(y,x,z);
}
dfs(1,0);
getcost(1,0);
for(i=1;i<=e;i++)
ans+=cost[i];
printf("%lld",ans);
return 0;
}