最小生成树prim算法

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INFINITY 30000    //定义一个权值的最大值
#define MAX_VERTEX_NUM 20 // 图的最大顶点数 
typedef struct
{
	int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵 
	int vexnum,arcnum;                // 图的当前顶点和边数 
}Graph;
typedef struct
{
	int adjvex;		// 某顶点与已构造好的部分生成树的顶点之间权值最小         的'顶点'
 	int lowcost;	// 某顶点与已构造好的部分生成树的顶点之间的最小权值 
}ClosEdge[MAX_VERTEX_NUM];	// 用普里姆算法求最小生成树时的辅助数组 
int min( ClosEdge closedge, int vexnum );
void CreateGraph(Graph *G);
void MiniSpanTree_PRIM(Graph *G,int u);
//==================================================

int main()
{
//	freopen( "in.txt", "r", stdin );
	Graph G;  //采用邻接矩阵结构的图
	char j = 'y';
	int u;
	printf("prim 算法构造最小生成树,严格按照严蔚敏书上实现\n");
	printf("首先输入图的顶点数和弧数.\n格式:顶点数,弧数;例如:4,4\n");
	printf("接着输入各条弧(弧尾,弧头)和弧的权值。\n");
	printf("格式:弧尾,弧头,权值;例如\n1,2,1\n1,3,2\n2,4,3\n3,4,4\n");
	printf("程序将会构造该图的最小代价生成树。\n");
	printf("并显示该最小生成树。\n1,2\n1,3\n2,4\n");
	while(j != 'N' && j!='n' )
	{
		CreateGraph( &G );       /* 生成邻接矩阵结构的图 */
		printf("从哪一顶点开始:");
		scanf( "%d", &u );  /* 输入普里姆算法中的起始顶点 */
		MiniSpanTree_PRIM( &G, u ); /* 普里姆算法求最小生成树 */
		printf("最小代价生成树构造完毕,继续进行吗?(Y/N)");
		fflush(stdin);   /*清除缓冲区*/
		scanf(" %c",&j);
	}
	return 0;
}


void CreateGraph(Graph *G )
{
	/* 构造邻接矩阵结构的图G */
 	int i,j;
 	int start,end,weight;
 	printf("请输入图的顶点数和弧数:");
 	scanf( "%d,%d", &G->vexnum, &G->arcnum ); /* 输入图的顶点数和边数 */
	for( i=1; i <= G->vexnum; i++ )
		for( j=1; j<=G->vexnum; j++ )
			G->arcs[i][j] = INFINITY; /* 初始化邻接矩阵 */
	printf("输入弧和其权值,格式:弧尾,弧头,权值\n");
	for( i=1; i <= G->arcnum; i++ )
	{
		scanf( "%d,%d,%d", &start, &end, &weight ); /* 输入边的起点和终点及权值 */
		G->arcs[start][end] = weight; 
		G->arcs[end][start] = weight;
	}

	/*调试代码
		for( i=1; i <= G->vexnum; i++ )
		{
			for( j=1; j<=G->vexnum; j++ )
			printf( "%d\t",  G->arcs[i][j] );
			printf( "\n" );
		}
	*/
}


void MiniSpanTree_PRIM(Graph *G,int u)
{
	/* 从第u个顶点出发构造图G的最小生成树 */
	ClosEdge closedge;
	int i,j,k,w;
	printf("最小代价生成树:\n");
	for( j=1;j <= G->vexnum; j++ ) /* 辅助数组初始化 */
	if( j != u )
	 {
		closedge[j].adjvex = u;
		closedge[j].lowcost = G->arcs[u][j]; 
	 }
	closedge[u].lowcost=0; /* 初始,U={u} */
	for( i=1; i < G->vexnum; i++ ) /* 选择其余的(G->vexnum) - 1个顶点 */
	{

		/*调试代码
			printf( "权值" );
			for( w = 1; w <= G->vexnum; w++ )
				printf( "%d ",  closedge[w].lowcost );
				printf( "\n" );
		*/
		k = min(closedge, G->vexnum);		//求出生成树的下一个顶点
		printf("%d,%d\n", closedge[k].adjvex, k ); // 输出生成树的边 
		closedge[k].lowcost=0;   //第k顶点并入U集 


				
		for(j=1; j <= G->vexnum; j++) /* 新顶点并入U后,修改辅助数组*/
			if( G->arcs[k][j] < closedge[j].lowcost )//更新过程																
			{										//如果新并入的点和U-V的权值小于和原点集V和U-V的权值,这更新数组,采用更小的权值
				closedge[j].adjvex = k;
				closedge[j].lowcost = G->arcs[k][j];
			}

				
		/*	调试代码
			printf( "权值" );
			for( w = 1; w <= G->vexnum; w++ )
				printf( "%d ",  closedge[w].lowcost );
				printf( "\n" );
		*/			
    }
}


/* 在辅助数组closedge[vexnum]中选择权值最小的顶点,并返回其位置 */
int min( ClosEdge closedge, int vexnum )
{
	int i;
	int w,p;
	w=INFINITY;
	for( i=1; i <= vexnum; i++ )
		if( closedge[i].lowcost != 0 && closedge[i].lowcost < w )
		{
			w = closedge[i].lowcost;
			p=i;
		}
		return p;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值