题目链接: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;
}