超详细的Prim算法解析

Prim算法 Prim算法适合玩捉迷藏~ 阅读详情

 最小生成树之Prim 算法

  • 什么是最小生成树?

我的理解:最小生成树,在一个无向图中,生成树必须包含这个无向图的所有顶点,且顶点与顶点之间必须有路,且这些路径不能形成一个环。而最小生成树就是在所有生成树当中,所以路径的的花费加起来最小的那一颗生成树。

想要知道最小生成树更正确的概念,可看书或自行百度!

 

如图所示,该无向图又三颗生成树,而最小生成树就是第二颗,花费为9。

 

  • prim算法求最短路径的思想

先在图中找一个最开始出发的顶点,开始出发,把出发的顶点先放入遍历的顶点集中,然后找到从这个顶点出发所有路径中花费最小的那条路径,然后把该路径能到达的顶点也放入遍历的顶点集中,然后接着找顶点集中所有顶点能出发通往未遍历的顶点的路径中最短的那条路径,然后选择这条路径,再把该路径到达的顶点放入遍历顶点集中,重复以上操作,直到所有的顶点都已经遍历完毕,算法结束,返回最小的花费。

 

 

 

如上图的无向图中,用prim求最短路的步骤就是:

一:选择v0顶点为出发点,将v0顶点放入已经遍历的顶点集合中,图中标蓝的就是已经遍历的顶点。从V0出发的路径有:

  1. v0到v1,花费为6
  2. v0到v2,花费为1
  3. v0到v3,花费为5

所以第二条路径花费最小,就选择它,花费cost=1

二:此时集合中有顶点v0和顶点v2。

从顶点v0出发符合条件的路径有:

  1. v0到v1,花费为6
  2. v0到v3,花费为5

从顶点v2出发符合条件的路径有:

  1. v2到v1,花费为5
  2. v2到v3,花费为5
  3. v2到v4,花费为6
  4. v2到v5,花费为4

所以从v2出发的第四条路径花费最小,就选择它,花费cost=1+4=5

三:此时集合中有顶点v0、顶点v2、顶点v5。

从顶点v0出发符合条件的路径有:

  1. v0到v1,花费为6
  2. v0到v3,花费为5(构成环路、不能选)

从顶点v2出发符合条件的路径有:

  1. v2到v1,花费为5
  2. v2到v3,花费为5(构成环路、不能选)
  3. v2到v4,花费为6

从顶点v5出发符合条件的路径有:

  1. v5到v3,花费为2
  2. v5到v4,花费为6

所以从v5出发的第一条路径花费最小,选择它,花费cost=1+4+2=8。

四:此时集合中有顶点v0、顶点v2、顶点v5、顶点v3。

从顶点v0出发符合条件的路径有:

  1. v0到v1,花费为6

从顶点v2出发符合条件的路径有:

  1. v2到v1,花费为5
  2. v2到v4,花费为6

从顶点v5出发符合条件的路径有:

  1. v5到v4,花费为6

从顶点v3出发没有符合条件的路径

所以从v2出发到顶点v1的路径花费最小,cost=1+4+2+5=12。

五:此时集合中有顶点v0、顶点v2、顶点v5、顶点v3、顶点v1。

从顶点v1出发符合条件的路径有:

  1. v1到v4,花费为3

从顶点v2出发符合条件的路径有:

  1. v2到v4,花费为6

从顶点v5出发符合条件的路径有:

  1. v5到v4,花费为6

所有从顶点v1出发到顶点v4的路径花费最小,cost=1+4+2+5+3=15。

六:此时集合中有顶点v0、顶点v2、顶点v5、顶点v3、顶点v1、顶点v4,所有顶点都已经遍历完毕,算法结束,求得的最小生成树的最小花费是15。

 

三:如何用代码去实现prim算法呢?

首先,我们需要三个数组:selected数组,用来判断节点是否被访问过;parent数组,用来记录上一个节点,也就是说选的这条路径是由parent记录的节点通往当前节点的。minCost数组,用来记录上一个节点到该点的最小花费;

来,为了更好的理解,上图(以上面的讲解图为例):

(1)先对各个数组进行初始化,每个数组初始化的数据如下图

 

(2)以第一个顶点为出发点,此时v0已经被选择了,所以把minCost的数组改为不可比较的状态,这样下一次选择的顶点需要通过比较minCost数组的值来获取,这样就可以保证选的是最小花费的那条边且不会形成环路了。以后选择一个顶点,就得把该顶点下的minCost数组对应的值改为X(不可比较的状态)这样才能保证不出现环路的情况。

 

(3)继续根据上图找到minCost数组中最小的值,是1,它对应的顶点是V2,则选择这个顶点,然后更新minCost数组和parent数组。更新条件时当前获得的minCost的值比原来记录的值要小。例如:V1顶点对应的原本的值6(v0到v1的花费),但是v2到v1的花费是5,比6小,就更新它。

 

(4)重复上述操作,可得到以下图解:

所以顶点都已经选择完毕了,算法结束。我们可以通过parent来还原最小生成树啦。

首先找到为-1的结点,发生是V0,所以路径为V0->……,接下来,找parent值为0的结点,发现是V2,所以V0->V2的边被选择,然后再找parent值为2的结点,是V1和V5,因此V2->V1,V2->V5的边被选择。然后分别找parent值为1、5的结点,发现是V2、V3,因此V1->V2,V5->V3的边被选中。

实现的代码如下:

题目:

Description

给出一个无向网,求该无向网的最小生成树。各条边的权重不超过100000。

本题与下一题的测试数据是一样的,本题请用Prim算法来做,以便与下一题做比较。

Input

输入的第一行是一个整数N,表示该网的顶点个数。 3 ≤ N ≤ 100

接下来是N行,每行N个整数,表示每个顶点到其余顶点的距离。

Output

输出该最小生成树的权重。

Sample Input

4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0

Sample Output

28

/*prim算法求最小生成树
邻接矩阵法构造图 
算法思想:首先从顶点0出发,然后找到下一个距离顶点0最近的顶点i,也进入集合U
此算法是从进入了集合U的顶点中找到个各顶点与其他未进入集合U的顶点之间的一条最短的边去连接的 
*/
# include<stdio.h>
#include<iostream>
using namespace std;
int inf=0x3f3f3f3f;
int s[100][100];//存储图 

bool selected[100];//判断顶点是否被选中 
int minCost[100];//保存已选顶点中到该顶点的最小的路径 
int parent[100];//保存父节点 
 
void prim(int n,int k){
	//第一步,第K个顶点被选中 
	selected[k]=true;
	minCost[k]=-1;
	//开始更新minCost数组和parent数组 
	for(int i=0;i<n;i++){
		if(s[k][i]!=inf&&s[k][i]<minCost[i]) {
			minCost[i]=s[k][i];
			parent[i]=k;
		}
	}
	//在minCost数组中找到最小的那个值,然后选择对应的点
	int min=inf;int f=-1;
	 for(int j=0;j<n;j++) {
	 	if(minCost[j]!=-1&&minCost[j]<min){
	 		min=minCost[j];
	 		f=j;
		 }
	 }
	 if(f==-1) return;//全部都已经被选了 
	 prim(n,f);
}
int main(void){
	//输入图的顶点个数
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			cin>>s[i][j];
			if(s[i][j]==0)
			s[i][j]=inf;
		}
		selected[i]=false; 
		minCost[i]=inf;
		parent[i]=-1;
	} 
	// cout<<"图输入完成!"; 
	 prim(n,0);
	 int sum=0;
	 for(int i=1;i<n;i++)
	 {
	 	sum=sum+s[i][parent[i]];
	 }
	 cout<<sum<<endl;
	 
}
/*6
0 6 1 5 0 0
6 0 5 0 3 0
1 5 0 5 6 4
5 0 5 0 0 2
0 3 6 0 0 6
0 0 4 2 6 0*/

这里用的是递归的方法去做,递归的方式理解是好理解,但是运行时所有的时间也会长一些,因为它的时间复杂度稿,我提交通过后显示的时间是25Ms,用的时间还是比较长的。所以要想运行时间快一些,就得降低一下时间复杂度,用迭代的方式去做这道题目应该会用时少一些。

 

 

 

 

prim算法(普里姆算法)详解 prim算法(普里姆算法)详解 了解了什么是最小生成树后,本节为您讲解如何用普里姆(prim)算法查找连通网(带权的连通图)中的最小生成树。 普里姆算法查找最小生成树的过程,采用了贪心算法的思想。对于包含 N 个顶点的连通网,普里姆算法每次从连通网中找出一个权值最小的边,这样的操作重复 N-1 次,由 N-1 条权值最小的边组成的生成树就是最小生成树。 那么,如何找出 N-1 条权值最小的边呢?普里姆算法的实现思路是: 将连通网中的所有顶点分为两类(假设为 A 类和 B 类)。初始状态下,所有顶点位于 B 阅读详情

相关推荐

Kruskal算法和Prim算法

Kruskal算法和Prim算法 在无向图中,连通且不含圈的图称为树。给定一个无向图G=(V,E),连通G中所有点,且边集使E的子集的树称为G的生成树,其中权值最小的生成树称为最小生成树(MST)。构造MST的算法有很多,最常见的即是Kruskal算法和Prim算法。 Kruskal算法 ...

weixin_55835175的博客 1258

prim算法

prim算法 prim算法(普利姆算法):对图G(V,E)设置集合S,存放已访问的顶点,然后每次从集合V-S中选择与集合S的最短距离最小的一个顶点(记为u),访问并加入集合S。之后,令顶点u为中介点,优化所有从u能到达的顶点v与集合S之间的最短距离。执行n次(n为顶点个数),直到集合S已包含所有顶点。 算法实例演示 首先让我们来看一个example。如下图所示,图a是一个连通图(右图是图a对应的邻接矩阵,假设图中的边的权值大于0),我们现在基于该图来演示Prim算法的过程。 我们选择一个起点,然后在与起

qq_36314864的博客 3万+

算法导论 23.2 Prim算法

一,Prim算法的思想        Prim算法和Kruskal算法一样对安全边的选择规则作出了细化,Prim每一步在连接集合A和A之外的结点的所有边中选择一条轻量边的结点信息加入A中,直到A中的结点覆盖所有结点。二,Prim算法介绍        准备阶段:一张赋值无向连通图,集合A用于存放最小生成树的各结点信息,每个结点有两个属性:key表示该结点的所有前驱结点到它的最短距离,π表示到它距离...

Koliday的学习之路 1033

最小生成树——Prim算法(详细图解)

最小生成树的概念 在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边,而 w(u, v) 代表此的边权重,若存在 T 为 E 的子集(即)且为无循环图,使得的 w(T) 最小,则此 T 为 G 的最小生成树。最小生成树其实是最小权重生成树的简称。 ...

qq_62213124的博客 22万+

算法——Prim算法

Prim算法是一种用于求解图的最小生成树的算法。该算法得名于美国计算机科学家罗伯特·普林姆(Robert C. Prim)。Prim算法的基本思想是从一个起始节点开始,并选择与当前生成树相连的边中权值最小的边,然后将该边加入到生成树中,再选择下一条权值最小的边,直到生成树覆盖了所有节点为止。祝您好运!

百锦再的博客 1万+

从零开始:在Windows WSL中搭建Openfoam7+blastfoam2.0.0开发环境(避坑大全)

本文详细指导在Windows WSL中搭建OpenFOAM 7与BlastFOAM 2.0.0开发环境,重点解析了安装过程中的常见“坑点”,如编译模式不匹配导致的符号错误,并提供了从系统准备、软件部署到环境验证的完整解决方案,帮助开发者高效构建CFD与爆炸模拟开发平台。

stem5的博客 526

Prim算法(858. Prim算法求最小生成树,朴素版Prim)(带图讲解,超详细)(带上了保存路径)

本专栏博客将会带大家讲解其中中有两种算法,一种是,Prim算法又分为朴素版的Prim(时间复杂度On2)和堆优化版的Prim(时间复杂度Omlogn)(跟Dijkstra算法分类一样,写法也很类似);另一种是(时间复杂度Omlogm朴素版Prim算法适合用稠密图,而堆优化版Prim和Kruskal算法适合用稀疏图。堆优化版的Prim算法很少用(99%用不到),所以本专栏博客不对其进行讲解。如果对稠密图和稀疏图的概念和构造还不清楚,可以参考和。

2301_77160836的博客 2676

射频工程师必须了解的S参数四项要点

本文围绕单端 6 英寸走线的 S 参数展开深入分析,核心包含四项关键要点:低频下导线电学长度远小于信号波长,S11 呈大负分贝值、S21 接近 0 分贝;端口与走线的阻抗不匹配引发反射叠加,形成 S11 首个峰值(对应传输线四分之一波长频率);S21 相位可作为一致性检查依据,其 90° 相位差与 S11 峰值吻合;理想建模中 S11 峰值随频率上升因损耗下降,实际测量因连接器等阻抗不连续性,S11 会出现振荡上升。分析依托 Keysight ADS 工具与电磁求解器原理,为 S 参数解读提供科学支撑。

一只豌豆象的博客 1284

prim算法的实现

添加链接描述 运行了一下prim 算法 觉得这个程序还可以 后期可以在此基础上做较大的改动 故此分享了这个代码 #include <stdio.h> #define MAXVEX 10 #define TRUE 1 #define FALSE 0 #define INF 65535//此处是权值极大值 #define LENGTH(a) (sizeof(a) / sizeof(a[...

Zyong139064359的博客 2527

用Matlab搞定Delta并联机器人运动学:从建模到正逆解完整流程(附代码)

本文详细介绍了如何使用Matlab实现Delta并联机器人的运动学分析,包括几何建模、正逆解求解及可视化验证。通过符号计算和数值迭代法,解决非线性方程组问题,并提供完整代码示例,帮助读者快速掌握Delta机器人的运动学计算与应用。

weixin_30955617的博客 176

Transformer是什么?看完这篇你就醍醐灌顶

前言 由谷歌团队提出的预训练语言模型BERT近年来正在各大自然语言处理任务中屠榜(话说学者们也挺有意思的,模型名都强行凑个芝麻街的人物名,哈哈哈)。 BERT算法的最重要的部分便是Transformer的概念,它本质上是Transformer的编码器部分。 而Transformer是什么呢?transformer是永远的神,自从transformer使用了抛弃rnncnn的纯attention机制之后,各种基于transformer结构的预训练模型都如雨后春笋般雄起,而transformer中最重要就是使用

fs1341825137的博客 6万+

Prim算法和Kruskal算法

Prim算法和Kruskal算法都能从连通图找出最小生成树。区别在于Prim算法是挨个找,而Kruskal是先排序再找。       一、Prim算法:     Prim算法实现的是找出一个有权重连通图中的最小生成树,即:具有最小权重且连接到所有结点的树。(强调的是树,树是没有回路的)。     Prim算法是这样来做的:      首先以一个结点作为最小生成

黄玮鹏的专栏 3万+

直线型一阶倒立摆1---从理论到实践的桥梁

本文深入探讨了直线型一阶倒立摆在控制理论中的核心地位,从非线性控制、鲁棒性到实时反馈等关键问题。通过实际案例和硬件搭建指南,帮助读者理解从理论到实践的过渡,特别适合控制工程初学者和研究人员。文章还提供了算法选型建议和硬件避坑手册,是掌握倒立摆控制的实用指南。

weixin_29047545的博客 318

prim算法 kruskal算法

如果是二维数组,来记录两个点链接,例如 parent[节点编号A][节点编号B] = 1 ,parent[节点编号B][节点编号A] = 1,来表示节点A与节点B相连,那就没有上面说的这个注意事项了,当然这么做的话,就是多开辟的内存空间。我在图中,特别把每条边的权值对应的是哪两个节点标记出来(例如minDist[7]=1,对应的是节点5和节点7之间的边,而不是节点6和节点7),为了就是让大家清楚,minDist里的每一个值对应的是哪条边。如果 一个图中,节点多,但边相对较少,那么使用Kruskal 更优。

波风水门的博客 889

AI Agent核心架构解析:从Tool、Skill到MCP协议的智能体构建实战

在人工智能领域,大语言模型(LLM)赋予了AI自主规划与决策的能力,推动了智能体(Agent)技术的演进。其核心原理在于构建一个具备感知、规划、行动与反思能力的自主系统。这一架构的技术价值在于将AI从被动应答升级为主动执行复杂任务的工作伙伴,显著提升了自动化水平与问题解决效率。应用场景广泛覆盖了市场分析、自动化办公、智能客服与垂直领域集成等。本文聚焦于实现这一能力的关键组件:基础工具(Tool)、组合技能(Skill)与标准化协议(MCP)。其中,Skill通过封装多个Tool形成可复用的高级能力,而MCP

chuannaoxuan4674的博客 321

【部署】Docker部署OpenClaw及常见问题解决(win11)

给AI单独开一个隔离的小容器,AI执行所有命令、下载文件都在这个小盒子里,就算AI被诱导执行危险命令,也不会影响你Win11本机的文件和系统,是必开的安全功能。Docker容器里的OAuth回调,会尝试在你Win11本机的1455端口捕获认证信息,但容器和Win11本机的网络隔离,导致浏览器访问不到这个回调地址。「挂载」就是把你Win11本机的文件夹,共享给容器里的「虚拟小电脑」,两边都能读写文件,比如你想让AI操作你D盘里的代码文件,就需要挂载。

海兰 4697

prim算法适用条件_Prim算法和Kruskal算法介绍

一、Prim算法普利姆(Prim)算法适用于求解无向图中的最小生成树(Minimum Cost Spanning Tree)。下面是Prim算法构造最小生成树的过程图解。 ...

weixin_39929635的博客 3228

uboot引导vxworks--t2080调试记录

开发环境: t2080rdb, uboot2015, vxworks7.01. 《VxWorks_7_fsl_t2t4_BSP_Supplement_Guide__SR0620.pdf》描述: 实际上默认创建的vip,profile选项为none时,vip内核配置中是包含了INCLUDE_END选项的。所以在创建vip的时候最好就添加上PROFILE_DEVELOPMENT。 2. 内核参数bootargs是一些网络参数设置=> pri bootargs bootargs=memac(1,0)b109304

珂珂可爱多 2640

prim算法适用条件_prim算法

算法分析的一般步骤:1、文字描述:如果一个算法文字描述不清楚,就说明思路不清楚,也不可能写好。prim算法是实现图的最小生成树。既然是图,就假设包含n个顶点,m条边。prim算法是从顶点出发的,其算法时间复杂度与顶点数目有关系。(注意:prim算法适合稠密图,其时间复杂度为O(n^2),其时间复杂度与边得数目无关,而kruskal算法的时间复杂度为O(eloge)跟边的数目有关,适合稀疏图。)算法...

weixin_39566773的博客 1837

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

上一篇: 多机调度问题(贪心)
下一篇: 位运算
神说要有光 ye
博客等级 码龄1天 463粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值