/**
*
* Coder: LinX 2017-7-15
*
* 内容: Prim算法计算无向图的最小生成树的权值
*
* 说明: 因为此算法的复杂度只与顶点数有关,因此适合于稠密图
*
*/
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
#define INF 1000
typedef struct
{
char data;
char info;
}VertexType;
typedef struct
{
int edges[MAXSIZE][MAXSIZE];
int vnums,enums; //顶点和边数目
VertexType vex[MAXSIZE];
}MGraph;
MGraph* createUDG(); //创建无向图
int prim(MGraph *G,int v0); //prim算法计算最小生成树的权值
int main()
{
int sum;
MGraph *G=createUDG();
sum=prim(G,0);
printf("最小生成树的权值为:%d",sum);
return 0;
}
/*prim算法计算最小生成树的权值*/
int prim(MGraph *G,int v0)
{
int vnums=G->vnums,
enums=G->enums,
i,j,
min=INF, //保存lowcost的最小值
newVT, //每次加进生成树的新顶点
k, //lowcost中最小权值的顶点
sum=0;
//vset保存每个顶点是否已经加入了生成树,lowcost保存当前生成树能到达每个顶点的最小权值
int vset[vnums],lowcost[vnums];
for(i=0;i<vnums;i++)
{
vset[i]=0;
//因为当前顶点为v0,将lowcost数组更新为v0所能到达的顶点的权值
lowcost[i]=G->edges[v0][i];
}
//当前生成树只有一个节点v0
vset[v0]=1;
//找出当前lowcost中的最小权值,相连接的顶点并入生成树
for(j=0;j<vnums-1;j++)
{
//这个地方尤其注意,如果不在这初始化一下,那么上一次求得的最小值就会影响这一次的
min=INF;
for(i=0;i<vnums;i++)
{
printf("第%d次:%d ",j+1,lowcost[i]);
if(vset[i]==0&&lowcost[i]<min)
{
min=lowcost[i];
//printf("%d ",min);
k=i;
}
}
vset[k]=1;
newVT=k;
//printf("%d ",min);
sum+=min;
//printf("%d ",sum);
for(i=0;i<vnums;i++)
{
//如果新加进来的顶点到其他顶点的权值有更小的那么更新更小的权值
if(vset[i]==0&&G->edges[newVT][i]<lowcost[i])
{
lowcost[i]=G->edges[newVT][i];
}
}
}
return sum;
}
/*创建无向图*/
MGraph* createUDG()
{
MGraph *G;
int n,m,i,j,v1,v2,weight;
char c;
G=(MGraph *)malloc(sizeof(MGraph));
printf("输入顶点个数 ");
scanf("%d",&n);
G->vnums=n;
printf("输入边的条数 ");
scanf("%d",&m);
G->enums=m;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
G->edges[i][j]=INF;
}
}
i=-1;
printf("输入顶点(#结尾): ");
while((c=getchar())!='#')
{
G->vex[i].data=c;
i++;
}
printf("输入边信息以及边的权值(输入一对顶点的位置): ");
for(i=0;i<m;i++)
{
scanf("%d%d%d",&v1,&v2,&weight);
G->edges[v1-1][v2-1]=weight;
G->edges[v2-1][v1-1]=weight;
}
printf("邻接矩阵为:\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d ",G->edges[i][j]);
}
printf("\n");
}
return G;
}
Prim算法
最新推荐文章于 2024-02-26 08:00:00 发布