http://acm.hdu.edu.cn/showproblem.php?pid=3371
输入一个T,代表有总共有T组测试数据,接下来一行输入n,m,k,其中n(3<=n<=500)表示城市的个数,m(0<=m<=25000)表示可以选择桥的个数,k(0<=k<=100)表示已连接的分块个数。接着,输入m行可供选择的桥的参数p,q,r,表示该桥连接p和q需要花费c(0<=c<=1000)。最后输入k行,其中,每行的第一个代表(t),代表有t个已经互相连接在一起的城市,然后,就是t个该城市的代号(1~n)。问:连接所有的城市,所需要的最小花费?若无法连接,则输出-1。
最小生成树问题
#include<cstdio>
#include<iostream>
using namespace std;
#define M 1000000
int a[600][600],aa[600],n;
void init()
{
int i,j;
for (i=0;i<=n;i++)
for (j=0;j<=n;j++)
if (i==j) a[i][j]=0;
else a[i][j]=M;
}
int main()
{
//freopen("a","r",stdin);
int i,j,m,c,b,r,k,t;
scanf("%d",&t);
for (int kk=1;kk<=t;kk++)
{
scanf("%d%d%d",&n,&m,&k);
init();
for (i=1;i<=m;i++)
{
scanf("%d%d%d",&b,&c,&r);
if (r<a[b][c])
{
a[b][c]=r;
a[c][b]=r;
}
}
for (i=1;i<=k;i++)
{
int n1;
scanf("%d",&n1);
for (j=1;j<=n1;j++) scanf("%d",&aa[j]);
int jj;
for (j=1;j<=n1;j++)
for (jj=j+1;jj<=n1;jj++)
a[aa[jj]][aa[j]]=a[aa[j]][aa[jj]]=0;
}
long long tp[600],dis[600],min,mk,dist=0;
for (i=1;i<=n;i++)
{
dis[i]=a[1][i];
tp[i]=0;
}
dis[1]=0;
tp[1]=1;
bool ff;
for (i=2;i<=n;i++)
{
min=M;
ff=false;
for (j=2;j<=n;j++)
if ((tp[j]==0)&&(dis[j]<min))
{
mk=j;
min=dis[mk];
ff=true;
}
if (ff==false) break;
dist+=dis[mk];
dis[mk]=0;
tp[mk]=1;
for (j=1;j<=n;j++)
if ((tp[j]==0)&&(a[mk][j]<dis[j])&&(mk!=j))
dis[j]=a[mk][j];
}
if (ff==false) printf("-1\n");
else printf("%lld\n",dist);
}
return 0;
}