题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3371
代码如下:
注意在杭电提交:G++会超时,可以用C++,可能是sort()函数的问题。
#include<iostream> #include<stdio.h> #include<memory.h> #include<algorithm> using namespace std; #define MAX 255003 int father[502]; int n,m,k; typedef struct Kruskal //存储边的信息 { int v1; int v2; int cost; }; Kruskal edge[MAX]; bool cmp(const Kruskal &a, const Kruskal &b) { return a.cost<b.cost; } /*int unionsearch(int x)//+路径压缩 { return x == father[x] ? x : unionsearch(father[x]); } */ int unionsearch(int x)//查找根结点 { int r=x; while(father[r]!=r) r=father[r]; return r; } int minCost() { int sum=0,cnt=0;//记录图的连通分量 for(int i=1;i<=n;i++) { if(father[i]==i) cnt++; } sort(edge+1,edge+1+m,cmp);//给边排序 for(int i=1;cnt>1&&i<=m;i++) { int fx=unionsearch(edge[i].v1); int fy=unionsearch(edge[i].v2); if(fx!=fy) { sum+=edge[i].cost; father[fx]=fy; cnt--; } } if(cnt==1) return sum; return -1; } int main() { int T,i,j; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&k); for(i=1;i<=n;i++)//并查集的初始化 { father[i]=i; } for(i=1;i<=m;i++) { scanf("%d%d%d",&edge[i].v1,&edge[i].v2,&edge[i].cost); } for(i=1;i<=k;i++) { int t; scanf("%d",&t); int f,s; scanf("%d",&f); for(j=1;j<t;j++) { scanf("%d",&s); father[unionsearch(s)]=father[unionsearch(f)];//保证联通支里只有一个祖先 f=s; } } int ans=minCost(); printf("%d\n",ans); } return 0; }