普里姆算法:每次寻找一条权值较少,且一个顶点在集合内,另一个不在集合内的边,添加到集合内,因为该点的添加导致其余dis[i]储存的非生成树点到生成树的距离改变,如果其余非生成树点到该点的距离比原来缩短了,那就改变dis[i]的值.
#include <stdio.h>
int main()
{
int dis[101];
int book[101];
int a[101][101];
int i,j,n,b,c,d,m,k,sum,count,min;
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (i==j) a[i][j]=0;
else a[i][j]=9999;
for (i=1;i<=m;i++)
{
scanf("%d%d%d",&b,&c,&d);
a[b][c]=d;
a[c][b]=d;
}
for(i=1;i<=n;i++)
dis[i]=a[1][i];
for (i=1;i<=n;i++)
book[i]=0;
book[1]=1;
sum=0;
count=1;
while(count<n)
{
min=9999;
for (i=1;i<=n;i++)//每次找距离树的最小边
if((book[i]==0)&&(dis[i]<min))//最小边不能被访问过
{
min=dis[i];
j=i;
}
book[j]=1;
count++;
sum=sum+min;//记录代价
for (k=1;k<=n;k++)
if ((book[k]==0)&&(dis[k]>a[j][k]))//r如果新增的点能够缩短非树顶点到生成树的距离(只需缩短未添加到集合内的点就可以了)(类似迪杰斯特拉算法)
{
dis[k]=a[j][k];
}
}
printf("%d\n",sum);
return 0;
}