普里姆算法

普里姆算法的基本思想如下:

假设N={V,{E}}是连通网,TE是N上最小生成树中边的集合。从U={u}开始,TE={}开始,重复执行下述操作:在所有的u属于U,v属于V-U的边(u,v)的边中找到权值最小的一条边,并且并入TE,同时u并入U,直到U=V;

先设一个辅助数组closedge[MAX],初始时先把第一个结点存入closedge[i].adjvex,令closedge数组中adjvex的初始值全部为v1结点,并把权值存入closedge[i].lowcost中,

每次执行算法时,从U-V中选取权值最小的一条边,并入TE。


#include <stdio.h>
#include <stdlib.h>
#define MAX 100

typedef int AdjMatrix[MAX][MAX];
typedef struct{
	char vexs[MAX];
	int vexnum,arcnum;
	AdjMatrix arcs;
}MGraph;
typedef struct{
	int lowcost;
	char adjvex;
}closedge[MAX];
typedef struct{
	closedge close;
}Edge;

int LocateAdj(MGraph &G, char v){
	int i;
	
	for(i = 0; i < G.vexnum; i ++){
		if(G.vexs[i] == v)
			return i;
	}
	
	return -1;
}

void CreateMGraph(MGraph &G){
	int i,j,k,cost;
	char v1,v2;
	
	scanf("%d%d",&G.vexnum,&G.arcnum);
	
	getchar();
	for(i = 0; i < G.vexnum; i ++){
		scanf("%c",&G.vexs[i]);
	}
	
	for(i = 0; i < G.vexnum; i ++){
		for(j = 0; j < G.vexnum; j ++){
			G.arcs[i][j] = 65537;
		}
	}
	
	for(k = 0; k < G.arcnum; k ++){
		getchar();
		scanf("%c%c",&v1,&v2);
		scanf("%d",&cost);
		
		i = LocateAdj(G,v1);	j = LocateAdj(G,v2);
		
		G.arcs[i][j] = G.arcs[j][i] = cost;
	}
}

void PRIM(MGraph G, int k){
	int i,j;
	Edge E;
	
	for(i = 0; i < G.vexnum; i ++){
		if(i != k){
			E.close[i].adjvex = G.vexs[k];
			E.close[i].lowcost = G.arcs[k][i];
		}
	} 
	E.close[k].lowcost = 0;
	
	for(i = 1; i < G.vexnum; i ++){
		int MinCost = 65537;
		
		for(j = 0; j < G.vexnum; j ++){
			if(E.close[j].lowcost < MinCost && E.close[j].lowcost){
				k = j;
				MinCost = E.close[j].lowcost;
			}
		}
		printf("(%c,%c)\n",E.close[k].adjvex,G.vexs[k]);
		
		E.close[k].lowcost = 0;
		
		for(j = 0; j < G.vexnum; j ++){
			if(G.arcs[k][j] < E.close[j].lowcost){
				E.close[j].adjvex = G.vexs[k];
				E.close[j].lowcost = G.arcs[k][j];
			}
		}
	}	
}

int main(){
	MGraph G;

	CreateMGraph(G);
	
	PRIM(G,0);
	
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值