版权声明:原创,未经作者允许禁止转载 https://blog.csdn.net/Mr_wuyongcong/article/details/86553318
正题
题目大意
给一个完全图的唯一一颗最小生成树,求完全图最小边权之和。
解题思路
我们考虑在计算最小生成树的时候,将两个联通块合并时,我们会选择连接这两个联通块的最小的边。
那么我们就可以让每个联通块合并时,让其他边都是比这个给出的边边权+1的就好了。
#include<cstdio>
#include<algorithm>
#define ll long long
#define N 20010
using namespace std;
struct node{
ll from,to,w;
}a[N];
ll ans,fa[N],s[N],t,n;
ll find(ll x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
bool cmp(node x,node y){
return x.w<y.w;
}
int main()
{
scanf("%lld",&t);
while(t--)
{
ans=0;
scanf("%lld",&n);
for(ll i=1;i<n;i++){
scanf("%lld%lld%lld",&a[i].from,&a[i].to,&a[i].w);
ans+=a[i].w;
}
for(ll i=1;i<=n;i++)
fa[i]=i,s[i]=1;
sort(a+1,a+n,cmp);
for(ll i=1;i<n;i++){
ll Fa=find(a[i].from),Fb=find(a[i].to);
ans+=(s[Fa]*s[Fb]-1)*(a[i].w+1);
fa[Fb]=Fa;s[Fa]+=s[Fb];
}
printf("%lld\n",ans);
}
}