题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3371
题意:就是给出你已知的m条路的长度和k个联通分量,让你找出最小的代价让他们都相通。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 505
#define M 25005
using namespace std;
int per[N];
int ca,n,m,k,p,q,c,t;
struct edge {
int s;
int e;
int val;
} a[M];
int cmp(edge x,edge y) {
return x.val<y.val;
}
int find(int x) {
return x==per[x]?x:per[x]=find(per[x]);
// while(x!=per[x])//while超时,必须压缩路径
// x=find(per[x]);
// return x;
}
void Union(int x,int y) {
int fx=find(x);
int fy=find(y);
if(fx!=fy)
per[fy]=fx;
}
int Kruscal() {
int ans=0;
sort(a,a+m,cmp);
for(int i=0; i<m; i++) {
int x=find(a[i].s);
int y=find(a[i].e);
if(x!=y)
{
ans+=a[i].val;
per[x]=y;
}
}
int tt=0;
for(int i=1; i<=n; i++) {
if(per[i]==i)
tt++;
if(tt>1) return -1;
}
return ans;
}
int main() {
scanf("%d",&ca);
while(ca--) {
scanf("%d%d%d",&n,&m,&k);
for(int i=1; i<=n; i++)
per[i]=i;
for(int i=0; i<m; i++) {
scanf("%d%d%d",&a[i].s,&a[i].e,&a[i].val);
}
while(k--) {
int t1,t2;
scanf("%d%d",&t,&t1);
t--;
while(t--) {
scanf("%d",&t2);
Union(t1,t2);
t1=t2;
}
}
printf("%d\n",Kruscal());
}
}