Prim算法

/**
 *
 *	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;
 }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值