题意:还是给你n个点,然后求最小生成树。特殊之处在于有一些点之间已经连上了边。
思路:裸的prim算法,有点不大于100,所以选O(n^2)的prim算法比较快一点。由于有些点事先已经连上了,读入的时候,把连上点的距离置零即可。
#include<cstdio>
#include<iostream>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
int map[105][105],n,dis[105];
void prim()
{
int vis[105],dis[105],k;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) dis[i]=inf;
dis[1]=0;
int ans=0;
for(int i=1;i<=n;i++)
{
int tmp=inf;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&dis[j]<tmp)
{
tmp=dis[j];
k=j;
}
}
vis[k]=1;
ans+=dis[k];
for(int j=1;j<=n;j++)
{
if(!vis[j]&&dis[j]>map[k][j])
dis[j]=map[k][j];
}
}
printf("%d\n",ans);
}
int main()
{
int m,a,b;
//freopen("t.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&map[i][j]);
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&a,&b);
map[a][b]=map[b][a]=0;
}
prim();
}
return 0;
}