题目链接
解题思路:
整条树的权值等于不同树链是权值的代数和,树链(u,v)为树上从u到v的路径。
一条树链的权值w(u,v)为这条树链上所有边的颜色的代数和。
所以,求整个树的权值就是求每条树链被经过的次数
所以每一条边的贡献=经过次数*该边权值
经过次数又等于 左边结点*右边结点
代码如下:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
vector<ll> a[maxn];
ll b[maxn];//经历的次数
ll ans,n;
ll dfs(ll u,ll v)
{
ll sum,i;
sum=1;
for(i=0;i<a[u].size();i++)
{
if(a[u][i]!=v)
{
sum+=dfs(a[u][i],u);
}
}
ans++;
b[ans]=sum*(n-sum);
return sum;
}
int main()
{
ll u,v,num=0,i;
cin>>n;
for(i=1;i<=n-1;i++)
{
cin>>u>>v;
a[u].push_back(v);
a[v].push_back(u);
}
dfs(1,-1);
sort(b+1,b+ans+1);
for(i=1;i<=ans;i++)
{
num+=b[i]*(ans-i+1);
}
cout<<num<<endl;
return 0;
}