题目大意:有n个村庄,已知任意两个村庄之间的距离,以及相连通的村庄的编号,求使n个村庄相连通的所需修建的最短道路的长度。
分析:用邻接矩阵表示两两村庄直接的距离,由于输入有已连通的村庄的标号,只需在原邻接矩阵的基础上,把已连通的村庄之间的距离更新为0就可以了,然后就是找出该带权图的最小生成树。
用Prime算法敲的代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 110
#define INF 999999999
bool s[MAX];
int dist[MAX],map[MAX][MAX];
void init(int n)
{
int i,j;
memset(s,false,sizeof(s));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j]=INF;
for(i=1;i<=n;i++)
map[i][i]=0;
}
int Prime(int n)
{
int i,j,k,mind,sum;
for(i=1;i<=n;i++)
dist[i]=map[1][i];
s[1]=true;
sum=0;
for(i=1;i<=n;i++)
{
mind=INF;
k=1;
for(j=1;j<=n;j++)
if(!s[j]&&dist[j]<mind)
{
k=j;
mind=dist[j];
}
s[k]=true;
sum+=dist[k];
for(j=1;j<=n;j++)
if(!s[j]&&dist[j]>map[k][j])
dist[j]=map[k][j];
}
return sum;
}
int main()
{
int m,n,i,j;
while(scanf("%d",&n)!=-1)
{
init(n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&map[i][j]);
scanf("%d",&m);
int a,b;
while(m--)
{
scanf("%d%d",&a,&b);
map[a][b]=map[b][a]=0;
}
printf("%d\n",Prime(n));
}
return 0;
}