思路:
首先这是一道最小生成树的题,看得出来
我们分析最小生成树的操作过程,是把没有合并的连通块合并,那么每个还未合并的联通快都一定是当前最优的情况,那么可以考虑用拆开来看。
如果要把两个连通块合并,那么肯定是找它们之间最短的边,其它的连边就舍去,那么其它的连边的和不就是我们要加上的吗,因为是最小,所以让它们都等于z+1就可以了
c o d e code code
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n, m;
struct node
{
long long x, y, z;
}a[1000010];
long long fa[1000010], num[1000010];
bool cmp(node x, node y)
{
return x.z<y.z;
}
long long find(long long x)
{
if(fa[x]==x)
return x;
else return fa[x]=find(fa[x]);
}
int main()
{
scanf("%lld", &n);
for(long long i=1; i<n; i++)
scanf("%lld%lld%lld", &a[i].x, &a[i].y, &a[i].z);
for(long long i=1; i<=n; i++)
fa[i]=i, num[i]=1;
sort(a+1, a+n, cmp);
long long ans=0;
for(long long i=1; i<n; i++)
{
long long fx=find(a[i].x), fy=find(a[i].y);
if(fx!=fy)
{
fa[fx]=fy;
ans+=(num[fy]*num[fx]-1)*(a[i].z+1)+a[i].z;
num[fy]+=num[fx];
}
}
printf("%lld", ans);
return 0;
}