图的最小生成树(MST)之Prim算法

Prim算法:确定给定图的最小生成树(MST)算法的实现 最小生成树(MST)是在一个加权连通图中找到一个子图,其中包含了所有顶点,并且总权值最小。Prim算法是一种常用的求解MST的算法之一,它以顶点为基础逐步构建MST。然后,我们创建了PrimMST对象,并调用FindMST方法来找到最小生成树。接下来,我们需要实现Prim算法来确定最小生成树。Prim算法的基本思想是从一个起始顶点开始,逐步选择与当前树连接的最小权值边的顶点,直到所有顶点都被包含在MST中。希望本文对你有所帮助!现在,我们可以使用上述代码来创建一个图并运行Prim算法来找到最小生成树。 阅读详情

普利姆(Prim)算法(只与顶点相关)

算法描述:

普利姆算法求最小生成树时候,和边数无关,只和定点的数量相关,所以适合求稠密网的最小生成树,时间复杂度为O(n*n)。

算法过程:

1.将一个图的顶点分为两部分,一部分是最小生成树中的结点(A集合),另一部分是未处理的结点(B集合)。

2.首先选择一个结点,将这个结点加入A中,然后,对集合A中的顶点遍历,找出A中顶点关联的边权值最小的那个(设为v),将此顶点从B中删除,加入集合A中。

3.递归重复步骤2,直到B集合中的结点为空,结束此过程。

4.A集合中的结点就是由Prim算法得到的最小生成树的结点,依照步骤2的结点连接这些顶点,得到的就是这个图的最小生成树。

为了实现Prim算法,假定对每一个不在A中的顶点v,都有一个配对顶点near(v),使得near(v)属于A,且cost(near(v),v)是所有可选的near(v)中代价最小的,假定(v,w)不属于E,那么cost(v,w)为正无穷。在Prim算法的每一步中,选取顶点v,使得cost(near(v),v)最小,且v不属于A。采取这种选择顶点的策略可以在O(n^2)时间内实现Prim算法。

代码(一种实现,将正无穷高换成零,修改判断的标准):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;

#define MAXN 110
int map[MAXN][MAXN], leastcost[MAXN];
bool visit[MAXN];
int nodenum, sum;

bool judge(int *a,int *b)
{
	if (*a == 0 )
	{ 
		if (*b == 0)
			return false;
		else
			return true;
	
	}
	else
	{
		if(*b == 0)
			return false;
		else
			if (*a > *b)
				return true;
			else
				return false;
	}
}
void prim(int nodenum)
{
	int temp, k;
	sum = 0;
	memset(visit, false, sizeof(visit)); //初始化visit
	visit[1] = true;  //置为true表示加入MST 
//	printf("->%d\n",1);
	for(int i = 1; i <= nodenum; ++i) //初始化leastcost[i]				 
		leastcost[i] = map[1][i];
	for(int i = 1; i <= nodenum; ++i)//找生成树集合点集相连最小权值的边
	{
		temp = 0;
		int s = 0;
		for(int j = 1; j <= nodenum; ++j)
			if(!visit[j] && judge(&temp , &leastcost[j]))
				temp = leastcost[k = j];
		if(temp == 0) break;
		for(s=1;s<=nodenum;s++)
			if(visit[s] && temp == map[s][k])
				break;
		visit[k] = true; //加入最小生成树集合
		
		printf("%d -> %d\n",s,k);
		sum += temp;//记录权值之和
		for(int j = 1; j <= nodenum; ++j) //更新leastcost数组
			if(!visit[j] && judge(&leastcost[j] ,&map[k][j]))
				leastcost[j] = map[k][j];
	}
}

int main()
{
	int a, b, weight, vertexnum,edgenum;
	scanf("%d%d",&vertexnum,&edgenum);
	memset(map, 0, sizeof(map));
	for(int i = 1; i <= edgenum; ++i) //输入边的信息
	{
		scanf("%d%d%d", &a, &b, &weight);
		map[a][b] = map[b][a] = weight;
	}
	prim(vertexnum);
	printf("%d\n", sum); //最小生成树权值之和

	return 0;
}

map初始化为某个大值(伪INF):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;

#define INT_MAX 0x3F3F3F3F
#define MAXN 110
int map[MAXN][MAXN], leastcost[MAXN];
bool visit[MAXN];
int nodenum, sum;


void prim(int nodenum)
{
	int temp, k;
	sum = 0;
	memset(visit, false, sizeof(visit)); //初始化visit
	visit[1] = true;  //置为true表示加入MST 
	//leastcost[] 表示 MST到 MST-V的最短距离 
	for(int i = 1; i <= nodenum; ++i)  
		leastcost[i] = map[1][i];
	for(int i = 1; i <= nodenum; ++i)//找生成树集合点集相连最小权值的边
	{
		temp = INT_MAX;
		int s = 0;
		for(int j = 1; j <= nodenum; ++j)
			if(!visit[j] && temp > leastcost[j])
				temp = leastcost[k = j];
		if(temp == INT_MAX) break;
		for(s=1;s<=nodenum;s++)
			if(visit[s] && temp == map[s][k])
				break;
		visit[k] = true; //加入最小生成树集合
		
		printf("%d -> %d\n",s,k);
		sum += temp;//记录权值之和
		for(int j = 1; j <= nodenum; ++j) //更新leastcost数组
			if(!visit[j] && leastcost[j] > map[k][j])
				leastcost[j] = map[k][j];
	}
}

int main()
{
	int a, b, weight, vertexnum,edgenum;
	scanf("%d%d",&vertexnum,&edgenum);
	memset(map, INT_MAX, sizeof(map));
	for(int i = 1; i <= edgenum; ++i) //输入边的信息
	{
		scanf("%d%d%d", &a, &b, &weight);
		map[a][b] = map[b][a] = weight;
	}
	prim(vertexnum);
	printf("%d\n", sum); //最小生成树权值之和

	return 0;
}
注意:这里INT_MAX设置为0x3f3f3f3f,是因为memset()以字节为单位填充map,即以INT_MAX的末尾的一个字节0x3f填充每一个字节,若是以INT_MAX中最后一个字节的第一位为1,假设大于0x7F,那么填充得到的整型值将是一个负值(4个字节一起解释为一个整型,首位符号位1,那么该整型值为负)。所以不能用“limits.h”中的INT_MAX(0x7FFFFFFF)作为此处memset(map,INT_MAX,sizeof(map))的实参。若是实在需要标准库INT_MAX,可以用for循环逐个赋值。

测试输入:

7 9
1 2 28
1 6 10
2 3 16
2 7 14
3 4 12
4 5 22
4 7 18
5 6 25
5 7 24
对应的图:

测试输出:

1 -> 6
6 -> 5
5 -> 4
4 -> 3
3 -> 2
2 -> 7
99
REF:

1,http://blog.youkuaiyun.com/niushuai666/article/details/6689295

2,数据结构(C语言版) Ellis Horowitz





Objective-C实现Prim 算法生成图的最小生成树MST算法(附完整源码) 阅读详情

相关推荐

JavaScript:实现Prim 算法生成图的最小生成树MST算法(附完整源码)

JavaScript:实现Prim 算法生成图的最小生成树MST算法(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 512

最小生成树(Prim)

题目描述 使用Prim算法求图的最小生成树(MST) 输入 每组数据分为两个部分,第一部分为图的点数n,和边数m, 第二部分为m行,每一行输入三个数字,前两个为两个顶点的编号,第三个为边权重。 输出 最小生成树,输出时按照边的两个端点的升序输出。(先看左端点,再看右端点,端点不换位置) 样例输入 Copy 3 3 0 1 10 0 2 15 1 2 50 样例输出 Copy 0 1 10 0 2 15 #include <iostream> #include <algorithm>

weixin_53488675的博客 551

C#:实现Prim算法确定给定图的最小生成树MST算法(附完整源码)

C#:实现Prim算法确定给定图的最小生成树MST算法(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 334

【Java】Prim最小生成树

题目描述 使用Prim算法求图的最小生成树(MST) 输入 每组数据分为两个部分,第一部分为图的点数n,和边数m, 第二部分为m行,每一行输入三个数字,前两个为两个顶点的编号,第三个为边权重。 输出 最小生成树,输出时按照边的两个端点的升序输出。(先看左端点,再看右端点,端点不换位置) 样例输入 Copy 3 3 0 1 10 0 2 15 1 2 50 样例输出 Copy 0 1 10 0 2 ...

weixin_43927892的博客 1656

go语言:实现Prim 算法生成图的最小生成树MST算法(附完整源码)

go语言:实现Prim 算法生成图的最小生成树MST算法(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 278

【网络协议】TCP的拥塞控制机制

前言 计算机网络中的带宽、交换节点中的缓存和处理机等,都是网络的资源,在某段时间内,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏,这种情况就叫做拥塞。 所谓拥塞控制,就是防止过多的数据注入到网络中,从而使网络中的路由器或链路不致过载。要注意用拥塞控制与流量控制的区别,拥塞控制是一个全局性的过程,涉及到所有的额主机、路由器,以及与降低网 拥塞控制的算法有:慢开始、拥塞避免、快重传、快恢复四种。 慢开始和拥塞避免 发送方维持一个拥塞窗口的状态变量,其大小取决于网络的拥塞程度

兰亭风雨的专栏 1万+

问题 F: 最小生成树(Prim)

问题 F: 最小生成树(Prim) 题目描述 使用Prim算法求图的最小生成树(MST) 输入 每组数据分为两个部分,第一部分为图的点数n,和边数m, 第二部分为m行,每一行输入三个数字,前两个为两个顶点的编号,第三个为边权重。 输出 最小生成树,输出时按照边的两个端点的升序输出。(先看左端点,再看右端点,端点不换位置) 样例输入 3 3 0 1 10 0 2 15 1 2 50 样例输出 0 1 10 0 2 15 解题思路 刚开始v集合只有一个结点,我这里用编号为0的结点 lowcost[i.

乐褀的博客 818

Yolov26 在 Rk3588 上的 Rknn Onnx 部署实践(模型转换)

本文详细介绍了将YOLOv26 ONNX模型转换为RKNN模型的过程,适用于RK3588平台。主要内容包括:1)量化数据集的创建,通过随机抽取最多400张JPG图片生成校准数据集;2)ONNX转RKNN的完整脚本,支持多种量化方式和平台适配;3)模型转换的参考调用方式;4)模型结构对比展示。文章还提供了注意事项,强调量化数据集图片尺寸、mean/std值需与实际推理一致,并给出精度优化建议。该转换流程为YOLOv26模型在RK3588上的高效部署提供了完整解决方案。

qq_64366203的博客 1126

Prim算法求MST(最小生成树)

Prim算法求最小生成树使用的图的存储结构是图的邻接矩阵 #include #define MAX_VERTAX_SIZE 20 #define INFINITE 65535 #define OK 1 #define ERROR 0 //图的邻接矩阵表示的结构定义 typedef int Status; typedef char VertaxElemType; typedef str

XuShuai 1465

【嵌入式】树莓派部署NCNN的YOLOv5模型

树莓派部署NCNN框架的YOLOv5模型

Ace_Spade的博客 3783

Python实战:5分钟搞定滑动平均窗口计算(附完整代码+逐行注释)

本文深入解析Python中滑动平均窗口计算的实现与优化,提供Numpy、Pandas等多种高效方案,并附完整代码和逐行注释。涵盖边界处理、性能优化及异常检测等实战技巧,帮助开发者快速掌握时间序列数据处理的核心技术。

weixin_30872157的博客 124

HNUCM-2022年秋季学期《算法分析与设计》练习14

HNUCM-2022年秋季学期《算法分析与设计》练习14

weixin_52470573的博客 1197

基于STM32设计的掌上游戏机(运行NES游戏模拟器)详细开发过程

利用STM32单片机移植NES游戏模拟器,完成NES游戏开发,可以玩标准的NES游戏,已测试超级玛丽、魂斗罗之类的都可以正常运行。

4万+

【算法与数据结构】图的最小生成树 MST - Prim 算法

Prim 算法属于贪心算法。 #include <stdio.h> #define VERTEXNUM 7 #define INF 10000 typedef struct Graph { int vertex[VERTEXNUM]; int edge[VERTEXNUM][VERTEXNUM]; } Graph; void initGraph(Graph* G) { int...

kikajack的博客 250

5G/NR 网络切片基本概念(协议版)

26.1 网络切片概念 网络切片是一个概念,可以根据每个客户的要求进行区别对待。通过切片的形式,将不同流量差异化处理,以及可以将资源进行隔离,然后移动网络运营商可以将客户视为属于不同租户类型的客户,每种客户具有不同的服务要求,这些要求根据每个租户根据SLA (Service Level Agreement,服务水平协议)可以使用哪种切片类型进行管理和订阅。 网络切片始终由RAN部分和CN部...

欢迎来到小七的博客,这里将带你深入探索5G通信的神秘世界。无论你是通信领域的专业人士还是对这一领域充满好奇心的技术爱好者,这里都有专业协议解读、通信知识普及以及有趣的Python编程内容等你发现。 1万+

C# USB通信实现

在C#中,我们可以利用.NET框架提供的类库和API来实现与USB设备的通信。本文将介绍如何使用C#进行USB通信,并提供相应的代码示例。以上就是使用C#进行USB通信的基本过程。通过以上代码示例,你可以实现与USB设备的简单通信,具体的实现方式和细节根据你的实际需求进行调整和扩展。命名空间,该命名空间包含了与串口通信相关的类和方法。选择需要通信的USB设备,然后使用。步骤二:获取可用的USB设备列表。首先,在你的C#项目中引入。步骤三:打开USB端口。步骤六:关闭USB端口。步骤一:引入命名空间。

PixelProX的博客 4383

图的最小生成树MST--Prim算法

带权值的网图通常会遇到这样一个问题:得到一个tuzho

尜尜君的小世界 5007

RT-DETR改进策略【损失函数篇】| 2024 引进Focaler-IoU损失函数 加强边界框回归 (Focaler-DIoU、Focaler-GIoU、Focaler-CIoU等)

本文记录的是改进RT-DETR的损失函数,将其替换成。现有研究通过利用边界框之间的几何关系来提高回归性能,但忽略了困难样本和简单样本分布对边界框回归的影响。不同检测任务中困难样本和简单样本的分布不同,对于简单样本占主导的检测任务,关注简单样本的边界框回归有助于提高检测性能;对于困难样本比例较高的检测任务,需要关注困难样本的边界框回归。,提高检测器在不同检测任务中的性能。实现的。

Limiiiing的博客 1922

【数据结构】六、图:5.图的最小生成树MST(普里姆(Prim)算法、克鲁斯卡尔(Kruskal)算法、Boruvka 算法)

它的基本思想是:生成树中所有顶点必然是连通的,所以两个不相交集必须连接起来才能构成生成树,而且所选择的连接边的权重必须最小,才能得到最小生成树。若(u,v)是一条具有最小权值的边,其中u∈U, v∈V-U,则必存在一棵包含边(u,v)的最小生成树。如果使用 O(mlog m) 的排序算法,并且使用 O(mα(m,n)) 或 O(mlog m) 的并查集,就可以得到时间复杂度为 O(mlog m) 的 Kruskal 算法。对于Boruvka算法,一个比较笼统的表述是,一个多路增广版本的Kruskal。

关注:https://github.com/Suhan42 1360

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

数据结构 — 图 之 MST(最小生成树 — prim算法 )

【描述】: 采用邻接矩阵方式储存图,创建图,生成最小生成树。 【输入】: 7 9 0 1 2 3 4 5 6 0 1 28 0 5 10 1 2 16 1 6 14 2 3 12 3 4 22 3 6 18 4 5 25 4 6 24 【输出】: 0,5权值: 10 | 5,4权值: 25 | 4,3权值: 22 | 3,2权值: 12 | 2,1

PeersLee的博客 2667

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

图的MST(最小生成树算法)Kruskral+Prim

前言 文章记录数据结构中求最小生成树的两种经典算法:Kruskal和Prim算法。 Kruskal算法算法的实现步骤: 个人理解:将图中所有的带权边按照权值大小(从小到大的次序)依次排序;形如<2,5>:3;<2,3>:4等,表示结点2到结点5能够连通,路径长度为3。 从上按照从小到大的‘顶点边权列表’中依次选择边权值最小且不构成环路的这些边形成最小生成树。 老师给的步骤:将所有的边按权值

Gerald_Jones的博客 2251

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Prim算法实现最小生成树MST(java)Prim算法是另一种生成图的最小生成树的算法,这里简单说一下Prim算法和Kruskal算法的在实现方面的区别: 1、Kruskal算法在生成最小生成树的

Prim算法是另一种生成图的最小生成树的算法,这里简单说一下Prim算法和Kruskal算法的在实现方面的区别: 1、Kruskal算法在生成最小生成树的过程中产生的是森林,Prim算法在执行过程中始终都是一棵树; 2、Kruskal和Prim实现上的最大区别是Kruskal不需要搜索每个顶点的邻接节点,而Prim中需要,所以Prim图构建时需要利用邻接链表进行构建,Kruskal不用! ...

不二的博客 563

洛谷P1265 公路修建——最小生成树,prim算法,不存图,边算边求MST

题目:https://www.luogu.org/problemnew/show/P1265 分析: 本质是求最小生成树。对于规则2,构成环则申请时去掉最大边。 因为最多有5000个点,又是完全图,故不采用Kruskal算法。 用Prim算法时,用邻接矩阵则会MLE。只有涉及到松驰点的权值时,再计算边长。 易错点: 计算两点间距离时,因为点的坐标是整数,因此要将坐标平方进行类型强制转换...

qq_36314344的博客 350

java实现图的最小生成树(MST)的普利姆(Prim)算法

/****************************************************************************** * Compilation: javac PrimMST.java * Execution: java PrimMST filename.txt * Dependencies: EdgeWeightedGraph.jav

小溪科技 1423

【数据结构】图论基石:最小生成树(MST)实战精解与Prim/Kruskal算法详解

【数据结构】第六章——图——图的基本应用 详细介绍图的基本应用——最小生成树的相关内容,从认识最小生成树到分析最小生成树的两种构建算法——Prim/Kruskal 的基本原理,最后再由基本原理总结出算法逻辑以及算法的适用范围……

蒙奇D索大的博客 1707
上一篇: 图的最小生成树(MST)之Kruskal算法
下一篇: 单源多目标最短路径之Dijkstra算法
Scandinavians
博客等级 码龄19年 36粉丝 121原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值