http://acm.hdu.edu.cn/showproblem.php?pid=3371 题意:给你一些分开的城市群,还给你一些城市相连的权值。让你求将所有城市相连所需的最小权值,不肯能输出-1. 解法:并查集。 #include <iostream> #include <algorithm> using namespace std; int n,m,k,father[501],ans; struct node { int u,v,c; }st[300000]; void init() { for(int i=0;i<=500;i++) father[i]=i; } int cmp(node a,node b) { return a.c<b.c; } int find(int x) { while(x!=father[x]) x=father[x]; return x; } void con(int x,int y) { int fx=find(x); int fy=find(y); father[fx]=fy; } int main() { int ncase; scanf("%d",&ncase); while(ncase--) { int i,j,num,a,b,root; init(); bool flag = false; scanf("%d%d%d",&n,&m,&k); for(i=1;i<=m;i++) scanf("%d%d%d",&st[i].u,&st[i].v,&st[i].c); sort(st+1,st+m+1,cmp); for(i=1;i<=k;i++) { scanf("%d%d",&num,&root); for(j=1;j<=num-1;j++) { scanf("%d",&a); if(find(a)!=find(root)) con(root,a); } } for(num=0,i=1;i<=n;i++) if(father[i]==i) num++; for(ans=0,i=1;i<=m;i++) { if(find(st[i].u)!=find(st[i].v)) { con(st[i].u,st[i].v); ans+=st[i].c;num--; } if(num==1) { flag = true; break; } } if(flag) printf("%d/n",ans); else printf("-1/n"); } return 0; }