最小生成树算法

#include <stdio.h>
#include <string.h>

#define INFINITY 1000000    // 无穷大
#define MAX_VERTEX_COUNT 6 // 图最多顶点数

// 图的邻接矩阵
typedef int Graph[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT];

/************************************************************************/
/* 功能:用Prim算法实现构造最小生成树
/* 参数:g--图
/*       vertexCount -- 图的顶点数
/*       father -- 记录顶点的双亲
/************************************************************************/
void Prim(Graph g, int vertexCount, int father[])
{
	int i, j, k;
    int lowCost[MAX_VERTEX_COUNT]; // 记录从U到V-U具有最小代价的边
	int closeSet[MAX_VERTEX_COUNT];// 记录了该边依附的在U中的顶点,v属于V-U
	int used[MAX_VERTEX_COUNT];    // 记录顶点是否已经被选中放入到U集合中
	int min;

	// 这里初始选中顶点为1号顶点,这是可以修改的,本程序以1号顶点为默认
	for (i = 0; i < vertexCount; i++)
	{
		// 最短距离初始化为其他节点到1号节点的距离
		lowCost[i] = g[0][i];

		// 标记所有节点的依附点皆为默认的1号节点
		closeSet[i] = 0;

		// 所有顶点均未被选中到U集合中
		used[i] = 0; 

		// U集合中还没有顶点,所有值设为-1,表示无双亲
		father[i] = -1;
	}

	used[0] = 1; // 1号顶点选中,并加入到集合U中
	// 依次选取剩余顶点加入到集合中
	for (i = 1; i < vertexCount; i++)
	{
		j = 0;
		min = INFINITY;

		// 找满足条件的最小权值边的顶点k及其编号
		for (k = 1; k < vertexCount; k++)
		{
			// 边权值较小且不在生成树中
			if (!used[k] && lowCost[k] < min)
			{
				min = lowCost[k]; // 选中顶点
				j = k;
			}
		}
		father[j] = closeSet[j]; // 记录j号顶点的双亲
		used[j] = 1; // 将j号顶点选入到生成树中

		// 打印边即打印该边连接的两个顶点(权值最小)
		printf("%d %d\n",j + 1,closeSet[j] + 1);

		for (k = 1; k < vertexCount; k++)
		{
			// 继续找边权值更小的顶点
			if (!used[k] && g[j][k] < lowCost[k])
			{
				lowCost[k] = g[j][k]; // 更新最小权值
				closeSet[k] = j; // 记录新的依附点
			}
		}
	}

}

int main()
{
	int i, j, weight;
    Graph g;
    int father[MAX_VERTEX_COUNT];
	int vertexCount;

	for (i = 0; i < MAX_VERTEX_COUNT; i++)
	{
		for (j = 0; j < MAX_VERTEX_COUNT; j++)
		{
			g[i][j] = INFINITY;
		}
	}

	// 构造图
	while (scanf("%d%d%d", &i, &j, &weight) != EOF)
	{
		// 无向图是对称的
		g[i - 1][j - 1] = weight;
		g[j - 1][i - 1] = weight;
	}

	Prim(g, 6, father);

	return 0;
}
时间: 2024-11-05 12:15:12

最小生成树算法的相关文章

[算法系列之二十七]Kruskal最小生成树算法

简介 求最小生成树一共有两种算法,一个是就是本文所说的Kruskal算法,另一个就是Prime算法.在详细讲解Kruskal最小生成树算法之前,让我们先回顾一下什么是最小生成树. 我们有一个带权值的图,我们要求找到一个所有生成树中具有最小权值的生成树.如下图所示,T是图G的生成树.但不是具有最小权值的生成树. 我们可以把他们想象成一组岛屿和连接它们的可能的桥梁.当然修桥是非常昂贵和费时的,所以我们必须要知道建设什么样的桥梁去连接各个岛.不过有一个重要的问题,建设这样一组连接所有岛屿的桥梁的最低价

最小生成树算法之Prim算法_C 语言

本文介绍了最小生成树的定义,Prim算法的实现步骤,通过简单举例实现了C语言编程. 1.什么是最小生成树算法? 简言之,就是给定一个具有n个顶点的加权的无相连通图,用n-1条边连接这n个顶点,并且使得连接之后的所有边的权值之和最小.这就叫最小生成树算法,最典型的两种算法就是Kruskal算法和本文要讲的Prim算法. 2.Prim算法的步骤是什么? 这就要涉及一些图论的知识了. a.假定图的顶点集合为V,边集合为E. b.初始化点集合U={u}.//u为V中的任意选定的一点 c.从u的邻接结点中

最小生成树算法:Kruskal算法的Java实现

闲来无事,写个算法,最小生成树的Kruskal算法,相对比Prim算法实现起来麻烦一点点 package trees; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.PriorityQueue; import java.util.Set; /** * 最小生成树的Kruskal算法, * For a connected weighted graph G, a s

[usaco]Agri-Net(使用最小生成树算法)

Agri-Net Russ Cox Farmer John has been elected mayor of his town! One of his campaign promises was to bring internet connectivity to all farms in the area. He needs your help, of course. Farmer John ordered a high speed connection for his farm and is

最小生成树算法C语言代码实例_C 语言

在贪婪算法这一章提到了最小生成树的一些算法,首先是Kruskal算法,实现如下: MST.h 复制代码 代码如下: #ifndef H_MST#define H_MST #define NODE node *#define G graph *#define MST edge ** /* the undirect graph start */typedef struct _node { char data; int flag; struct _node *parent;} node; typede

算法研究:图解最小生成树之普里姆算法

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

贪心算法(2)-Kruskal最小生成树

什么是最小生成树? 生成树是相对图来说的,一个图的生成树是一个树并把图的所有顶点连接在一起.一个图可以有许多不同的生成树.一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边.最小生成树其实是最小权重生成树的简称.生成树的权重是考虑到了生成树的每条边的权重的总和. 最小生成树有几条边? 最小生成树有(V – 1)条边,其中V是给定的图的顶点数量. Kruskal算法 下面是步骤寻找MST使用Kruskal算法 1 1,按照所有边的权重

Prim算法-最小生成树

基本思想: 1 置S={1} 2 只要S是V的真子集就做如下的贪心选择: 选取满足条件的i ,i属于S,j输入V-S,且c[i][j]最小的边,并将定点j加入S中 这个过程直到S==V为止. 3 这个过程所选的边,恰好就是最小生成树 算法描述: void Prim(int n,Type * * c) { T = 空集; S = {1}; while(S != V) { (i,j)=i 属于 S 且 j属于V-S的最小权边; T = T∪{(i,j)}; S = S ∪ {j}; } } 模版代码

poj 3522 Slim Span:枚举+最小生成树

链接: http://poj.org/problem?id=3522 题目: Slim Span Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4962   Accepted: 2587 Description Given an undirected weighted graph G, you should find one of spanning trees specified as follows. The grap