题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3371
Connect the Cities
题目大意:给你n个点,再给你m条路的花费(要修的),再给你k条路是已经修好的,然后让你求,将所有点联通,至少还需要多少花费。实质上就是要你求一条最小生成树,已经修好的路,花费置为0,然后用prim算法求解即可!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0xfffffff
using namespace std;
int n,m,l;
int edge[510][510];
int vis[510];
int aa[510];
int prim()
{
int i,j,p;
int MIN,res=0,dis[510];
memset(vis,0,sizeof(vis));
vis[1]=1;
for(i=2;i<=n;i++)
dis[i]=edge[1][i];
for(i=2;i<=n;i++)
{
MIN=INF;p=-1;
for(j=1;j<=n;j++)
{
if(!vis[j]&&MIN>dis[j])
{
MIN=dis[j];
p=j;
}
}
if(INF==MIN)
return -1;
res+=MIN;
vis[p]=1;
for(j=1;j<=n;j++)
if(!vis[j]&&dis[j]>edge[p][j])
dis[j]=edge[p][j];
}
return res;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,j,a,b,c,ans=0;
scanf("%d%d%d",&n,&m,&l);
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
{
edge[i][i]=0;
edge[i][j]=edge[j][i]=INF;
}
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
edge[a][b]=edge[b][a]=min(edge[a][b],c);
}
for(i=0;i<l;i++)
{
int t;
scanf("%d",&t);
for(j=0;j<t;j++)
scanf("%d",&aa[j]);
for(j=0;j<t-1;j++)
edge[aa[j+1]][aa[j]]=edge[aa[j]][aa[j+1]]=0;
}
ans=prim();
printf("%d\n",ans);
}
return 0;
}