走廊泼水节
给定一颗树,把它扩充成完全图.求需要的最小边权和
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)\) 合并时直接加到根上

浙公网安备 33010602011771号