hdu 3371 Connect the Cities (最小生成树Prim)

时间:2021-10-31 14:07:02

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3371

题目不难 稍微注意一下 要把已经建好的城市之间的花费定义为0,在用普通Prim算法就可以了;我没有用克鲁斯卡尔算法(Kruskal's algorithm),因为这题数据比较大,而且要处理大量的数据使它为0,怕超时T^T。。。。。

 #include<iostream>
#include<cstdio>
#include<algorithm> using namespace std; #define inf 999999 int map[][],node[],n,vis[];
int dd[],sum; int Prim()
{
int tm=;
node[tm]=;
//vis[tm]=1;
for(int k=;k<=n;k++)
{
int minn=inf;
for(int i=;i<=n;i++)
if(!vis[i]&&minn>node[i])
{
tm=i;
minn=node[i];
}
vis[tm]=;
if(minn==inf)
return ; sum+=minn; for(int i=;i<=n;i++)
{
if(!vis[i]&&node[i]>map[tm][i])
node[i]=map[tm][i];
}
}
return ;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n;i++)
{
node[i]=inf;vis[i]=;
for(int j=;j<=n;j++)
map[i][j]=inf;
}
while(m--)
{
int a,b,d;
scanf("%d%d%d",&a,&b,&d);
if(map[a][b]>d)
map[a][b]=map[b][a]=d;
}
while(k--)
{
int t;
scanf("%d",&t);
for(int i=;i<=t;i++)
{
scanf("%d",&dd[i]);
}
for(int i=;i<=t;i++)
{
for(int j=i+;j<=t;j++)
map[dd[i]][dd[j]]=map[dd[j]][dd[i]]=;
}
}
sum=;
int flag=Prim();
if(flag==)
printf("-1\n");
else
printf("%d\n",sum);
}
return ;
}