走廊泼水节

给定一颗树,把它扩充成完全图.求需要的最小边权和

struct Edge
{
	int x,y,z;
}e[N];
int T,n;
int fa[N],sz[N];
int get(int x)
{
	if(x==fa[x]) return x;
	return fa[x]=get(fa[x]);
}

bool cmp(Edge x,Edge y){ return x.z<y.z;}

int main()
{
	T=read();
	while(T--)
	{
		n=read();
		for(int i=1;i<=n;i++) fa[i]=i,sz[i]=1;
		for(int i=1;i<n;i++)
		{
			int x=read(),y=read(),z=read();
			e[i]=(Edge){x,y,z};
		}
		sort(e+1,e+n,cmp);
		ll ans=0;
		for(int i=1;i<n;i++)
		{
			int x=e[i].x,y=e[i].y,z=e[i].z;
			int fx=get(x),fy=get(y);
			fa[fx]=fy;//fx的爸爸赋值为fy 
			ans+=((ll)z+1)*( (ll)sz[fx]*sz[fy]-1); 
			sz[fy]+=sz[fx];
		}
		printf("%d\n",ans);
	}
	return 0;
}

带集合大小的并查集 只需要\(size[fx]+=size[fy]\) 即可

合并是注意是\(fa[get(x)]=get(y)\) 合并时直接加到根上

posted @ 2022-01-15 17:40  __iostream  阅读(27)  评论(0)    收藏  举报