jzoj2940-生成输入数据【最小生成树,并查集】

版权声明:原创,未经作者允许禁止转载 https://blog.csdn.net/Mr_wuyongcong/article/details/86553318

正题


题目大意

给一个完全图的唯一一颗最小生成树,求完全图最小边权之和。


解题思路

我们考虑在计算最小生成树的时候,将两个联通块合并时,我们会选择连接这两个联通块的最小的边。
那么我们就可以让每个联通块合并时,让其他边都是比这个给出的边边权+1的就好了。


c o d e code

#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);
	}
}

猜你喜欢

转载自blog.csdn.net/Mr_wuyongcong/article/details/86553318
今日推荐