#include<stdio.h>
#include<stdlib.h>
#define MAX 100
#define MAXCOST 0x7fffff
int graph[MAX][MAX];
int Prim(int graph[][MAX],int n)
{
//lowcost[i]记录的是以结点i为终点的最小权边,初始化默认吧第一个结点加入到生成树
//所以lowcost[i]=grahp[1][i],即最小边权值就是各个结点到1号结点的边权值
//mst[i]记录的是lowcost[i]对应的起点,初始化mst[i]=1
int lowcost[MAX];
int mst[MAX];
int i,j,minn,minid,sum=0;
//默认选择1号节点加入生成树,从1号结点开始初始化
for(i=2;i<=n;i++)
{
lowcost[i]=graph[1][i];
mst[i]=1;
}
mst[1]=0;
for(i=2;i<=n;i++)
{
minn=MAXCOST;
minid=0;
//找到满足条件的最小权值边的结点minid
for(j=2;j<=n;j++)
{
//边权值较小且不再生成树中
if(lowcost[j]<minn && lowcost[j]!=0)
{
minn=lowcost[j];
minid=j;
}
}
//输出生成树边的信息:起点,中点,权值
printf("%c -> %c : %d\n",mst[minid]+'A'-1,minid+'A'-1,minn);
//累加权值
sum+=minn;
lowcost[minid]=0;
//更新当前结点minid到其他结点的权值
for(j=2;j<=n;j++)
{
//发现更小的权值
if(graph[minid][j]<lowcost[j])
{
lowcost[j]=graph[minid][j];
mst[j]=minid;
}
}
}
//返回最小权值和
return sum;
}
int main()
{
int i,j,k,m,n;
int x,y,cost;
char chx,chy;
//读取结点和边的数目
scanf("%d%d",&m,&n);
getchar();
for(i=1;i<=m;i++)
{
for(j=1;j<=m;j++)
{
graph[i][j]=MAXCOST;
}
}
//读取边信息
for(k=1;k<=n;k++)
{
scanf("%c %c %d",&chx,&chy,&cost);
getchar();
i=chx-'A'+1;
j=chy-'A'+1;
graph[i][j]=cost;
graph[j][i]=cost;
}
for(i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
printf("%5d ",graph[i][j]);
printf("\n");
}
//求解最小生成树
cost=Prim(graph,m);
printf("Total:%d\n",cost);
return 0;
}
Prim算法
最新推荐文章于 2024-08-10 22:59:54 发布