图的最小生成树之普里姆Prim算法

源代码如下:

#include<iostream>
using namespace std;
#define MAX_VERTEX_NUM 20
#define infinity 9
typedef int QElemType;
typedef int EdgeData;
typedef char VertexData;
typedef struct
{
    VertexData verlist[MAX_VERTEX_NUM];            //顶点表
     EdgeData edge[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵--可试为边之间的关系
     int vexnum,edgenum;                          //顶点数和边数
}MTGraph;

void printMTGragh(MTGraph *G){
	int i,j;
	for (i = 1 ; i <= G->vexnum ; i++){
		for (j = 1 ; j <= G->vexnum ; j++)
			cout<<G->edge[i][j]<<" ";
		cout<<endl;
	}
//	Prim(G,G->edge);
}

void Prim(MTGraph *G){             //集合V-U的顶点尚未加入最小生成树中,集合U则已加入
	int lowcost[MAX_VERTEX_NUM+1]; //用来保存集合V-U中各顶点与集合U中顶点最短边的权值,
								   // lowcost[v] = infinity 表示顶点V已加入了最小生成树中 

	int closest[MAX_VERTEX_NUM+1]; //用来保存依附于该边的在集合U的顶点
									// 该边:集合V-U中各顶点与集合U中顶点最短边
	int i,j,k,h,min;
//	printMTGragh(G);
	for(i = 2;i<=G->vexnum;i++){
		lowcost[i] = G->edge[1][i];
		closest[i] = 1;  //将定点1加入集合U中
	}
	for(i = 2;i<=G->vexnum;i++){
		min = 9 ;
		k = i;
		for(j=2;j<=G->vexnum;j++)
			if(lowcost[j] < min && lowcost[j]!=0){
				min = lowcost[j]; //在 lowcost中取最小边
				k = j;
			}
		cout<<"将第"<<i<<"个元素放入集合U中时,Lowcost原序列:";
		for(h = 2;h<=G->vexnum;h++)
			cout<<lowcost[h]<<" ";
		cout<<endl;
		cout<<"("<<k<<","<<closest[k]<<")"<<endl; //输出顶点K与之对应的权值
		cout<<"取出的顶点为:"<<k<<"将顶点"<<k<<"与顶点"<<closest[k]<<"相连"<<endl;
		lowcost[k] = 0;  //将顶点K置于集合U中 

		for(j=2;j<=G->vexnum;j++) //调整数组lowcost和 cloest
			if(G->edge[k][j]<lowcost[j]){
				lowcost[j] = G->edge[k][j];
				closest[j] = k;
			}
		cout<<"将第"<<i<<"个元素放入集合U中时,Lowcost更新后的序列:";
		for(h = 2;h<=G->vexnum;h++)
			cout<<lowcost[h]<<" ";
		cout<<endl;
	}
}  //时间复杂度O(n^2)
//建立图的邻接矩阵
void createMTGraph(MTGraph *G){
	int i,j,k,w;
	cout<<"输入顶点数和边数如(5 7)"<<endl;
	cin>>G->vexnum>>G->edgenum;
	cout<<"输入顶点信息,如(A B C D...)"<<endl;
	for(i = 0 ; i<G->vexnum;i++)
		cin>>G->verlist[i];
	for(i = 0 ; i<=G->vexnum;i++)
		for(j = 0 ; j<=G->vexnum;j++)
			G->edge[i][j] = infinity;

	cout<<"输入边(i,j)上的权值w,如(i j w)"<<endl;
	 for(k=0;k<G->edgenum;k++){
	 	cin>>i>>j>>w;
	 	G->edge[i][j] = w;
	 	G->edge[j][i] = w;
	 }
}

main(){
	MTGraph *G ;
	G = new MTGraph();
	createMTGraph(G);
	printMTGragh(G);
	Prim(G);
	system("pause");
}

程序运行后的结果

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 23:41:47

图的最小生成树之普里姆Prim算法的相关文章

图的最小生成树(普利姆prim算法)

什么是生成树呢? 一个连通图的生成树是指一个极小连通子图, 它含有图中的全部顶点,但只有足以构成一棵树的n-1条边. 什么是最小生成树? 在一个连通图的所有生成树中,各边的代价之和最小的那棵生成树称为该连通图的最小代价生成树(MST), 简称最小生成树. 求最小生成树有两种算法,本文讲prim算法. 简略证明 使用反证法证明 设一棵最小生成树T不包含最短边a,将a加入最小生成树T中,书中必定构成一个包含a的回路,而回路中必定有边比a大(因a为最短边),则删除比a大的边得到一棵比原先T更小的树T1

普里姆Prim算法 - 图解最小生成树

我们在图的定义中说过,带有权值的图就是网结构.一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边.所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使得权值的和最小.综合以上两个概念,我们可以得出:构造连通网的最小代价生成树,即最小生成树(Minimum Cost Spanning Tree). 找连通图的最小生成树,经典的有两种算法,普里姆算法和克鲁斯卡尔算法,这里介绍普里姆算法. 为了能够讲明白这个算法,我们先构造网图的邻接矩阵,

普里姆(Prim)算法

1 /* 2 普里姆算法的主要思想: 3 利用二维数组把权值放入,然后找在当前顶点的最小权值,然后走过的路用一个数组来记录 4 */ 5 # include <stdio.h> 6 7 typedef char VertexType;//定义顶点类型 8 typedef int EdgeType;//定义边上的权值类型 9 # define MAX_VERTEX 100//最大顶点个数 10 # define INFINITY 65535//用65535代表无穷大 11 12 typedef

数据结构(五)图---最小生成树(普里姆算法)

一:最小生成树 (一)定义 我们把构造连通网的最小代价生成树称为最小生成树 (二)什么是最小生成树? 1.是一棵树 1)无回路 2)N个顶点,一定有N-1条边 2.是生成树 1)包含全部顶点 2)N-1条边都在图中 3.边的权重和最小 (三)案例说明 在实际生活中,我们常常碰到类似这种一类问题:如果要在n个城市之间建立通信联络网, 则连通n个城市仅仅须要n-1条线路.这时.我们须要考虑这样一个问题.怎样在最节省经费前提 下建立这个通信网.换句话说,我们须要在这n个城市中找出一个包括全部城市的连通

ACM第四站————最小生成树(普里姆算法)

对于一个带权的无向连通图,其每个生成树所有边上的权值之和可能不同,我们把所有边上权值之和最小的生成树称为图的最小生成树. 普里姆算法是以其中某一顶点为起点,逐步寻找各个顶点上最小权值的边来构建最小生成树. 其中运用到了回溯,贪心的思想. 废话少说吧,这个其实是一个模板,直接套用就好!直接上题吧!这些东西多练就好! 一.最小生成树: 题目描述 求一个连通无向图的最小生成树的代价(图边权值为正整数). 输入 第 一行是一个整数N(1<=N<=20),表示有多少个图需要计算.以下有N个图,第i图的第

图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用

图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 B(G).其中 T(G)是遍历图时所经过的边的集合,B(G) 是遍历图时未经过的边的集合.显然,G1(V, T) 是图 G 的极小连通子图,即子图G1 是连通图 G 的生成树. 深度优先生成森林   右边的是深度优先生成森林: 连通图的生成树不一定是唯一的,不同的遍历图的方法得到不同的生成树;从不

数据结构例程——最小生成树的普里姆算法

本文是[数据结构基础系列(7):图]中第11课时[最小生成树的普里姆算法]的例程. (程序中graph.h是图存储结构的"算法库"中的头文件,详情请单击链接-) #include <stdio.h> #include <malloc.h> #include "graph.h" void Prim(MGraph g,int v) { int lowcost[MAXV]; //顶点i是否在U中 int min; int closest[MAXV]

数据结构之---C语言实现最小生成树之prim(普里姆)算法

//最小生成树之Prim算法 //杨鑫 #include <stdio.h> #include <stdlib.h> #define n 6 #define MaxNum 10000 /*定义一个最大整数*/ /*定义邻接矩阵类型*/ typedef int adjmatrix[n + 1][n + 1]; /*0号单元没用*/ typedef struct { int fromvex, tovex; //生成树的起点和终点 int weight; //边的权重 }Edge; ty

最小生成树(普里姆算法)

最小生成树prim算法实现: 转自:http://www.cnblogs.com/Veegin/archive/2011/04/29/2032388.html 所谓生成树,就是n个点之间连成n-1条边的图形.而最小生成树,就是权值(两点间直线的值)之和的最小值. 首先,要用二维数组记录点和权值.如上图所示无向图: int map[7][7];       map[1][2]=map[2][1]=4;       map[1][3]=map[3][1]=2;       ...... 然后再求最小