最小生成树prim算法详解

devtools/2024/9/24 6:27:44/

prim算法解决的是最小生成树问题,即在一个给定的无向图G中求一棵生成树T,使得这棵树拥有图G中的所有顶点,且所有边都是来自图G中的边,并且满足整棵树的边权之和最小。

prim算法的基本思想是对图G设置集合S来存放已被访问的顶点,然后执行n次下面的两个步骤:

(1)每次从集合V-S中选择与集合S最近的一个顶点(记为u),访问u并将其加入集合S,同时把这条离集合S最近的边加入到最小生成树中。

(2)令顶点u作为集合S与集合V-S连接的接口,优化从u能到达的未访问顶点v与集合S的最短距离

prim算法和Dijkstra算法使用的思想几乎完全相同。只有在数组d[]的含义上有所区别。其中,Dijkstra算法的数组d[]含义为起点s到达顶点Vi的最短距离,而prim算法的数组d[]含义为顶点Vi与集合S的最短距离,两者的区别仅在于最短距离是顶点Vi针对“起点s”还是“集合S”。另外,对最小生成树问题而言,如果仅是求最小边权之和,那么在prim算法中就可以随意指定一个顶点为初始点,例如在下面的代码中默认使用0号顶点为初始点。实现的伪代码如下:

Prim(G,d[]){初始化;for(循环n次){u=使d[u]最小的还未被访问的顶点的标号;记u已被访问;for(从u出发能到达的所有顶点v){if(v未被访问&&以u为中介点使得v与集合S的最短距离d[v]更优){将G[u][v]赋值给v与集合S的最短距离d[v]; }} } 
}

下面给出分别使用邻接矩阵和邻接表的prim算法代码:

(1)邻接矩阵版

const int maxn=1000;
const int INF=1000000000;
int n,G[maxn][maxn];
int d[maxn];
bool vis[maxn]={false};
int prim(){//默认0为起始点,函数返回最小生成树的边权之和 fill(d,d+maxn,INF);d[0]=0;int ans=0;for(int i=0;i<n;i++){int u=-1,MIN=INF;for(int j=0;j<n;j++){//找到未访问的顶点中d[]最小的 if(vis[j]==false&&d[j]<MIN){u=j;MIN=INF;}}if(u==-1){return -1;}vis[u]=true;ans+=d[u];for(int v=0;v<n;v++){if(vis[v]==false&&G[u][v]!=INF&&G[u][v]<d[v]){d[v]=G[u][v];}}}return ans;
}

(2)邻接表版

struct node{int v,dis;
};
vector<node> Adj[maxn];
int n;
int d[maxn];
bool vis[maxn]={false};
int prime(){fill(d,d+maxn,INF);d[0]=0;int ans=0;for(int i=0;i<n;i++){int u=-1,MIN=INF;for(int j=0;j<n;j++){if(vis[j]==false&&d[j]<MIN){u=j;MIN=d[j];}}if(u==-1){return -1;}vis[u]=true;ans+=d[u];for(int j=0;j<Adj[u].size();j++){int v=Adj[u][j].v;if(vis[v]==false&&Adj[u][j].dis<d[v]){d[v]=Adj[u][j].dis;}}}return ans;
}

和Dijkstra算法一样,使用这种写法的复杂度为O\left ( V^{2} \right ),其中邻接表实现的prim算法可以使用堆优化使时间复杂度降为O\left ( VlogV+E \right )。所以尽量在图的顶点数目较少而边数较多的情况下使用prim算法


http://www.ppmy.cn/devtools/53682.html

相关文章

基于文本和图片输入的3D数字人化身生成技术解析

随着虚拟现实、增强现实和元宇宙等技术的飞速发展,对高度逼真且具有表现力的3D数字人化身的需求日益增长。传统的3D数字人生成方法往往需要依赖大量的3D数据集,这不仅增加了数据收集和处理的成本,还限制了生成的多样性和灵活性。为了克服这些挑战,我们提出了一种基于文本提…

Linux环境下,怎么排查os中系统负载过高的原因瓶颈?

在Linux环境下排查系统负载过高的原因和瓶颈&#xff0c;可以采取以下步骤&#xff1a; 使用top或htop命令观察系统整体负载情况。查看load average的值&#xff0c;分别表示系统在1分钟、5分钟和15分钟内的平均负载。如果负载值超过CPU核心数量的70-80%&#xff0c;表示系统负…

LaTeX 学习 第2节 数学结构

----用教授的方式学习 目录 2.1 上标与下标 2.2 上下画线与花括号 2.3 分式 2.4 根式 2.5 矩阵 ​​​​​​​LaTex安装包&#xff1a;https://download.csdn.net/download/weixin_38135241/89416392 LaTex- windows安装包&#xff1a;https://download.csdn.net/down…

用ip link add link命令创建vlan子设备

用ip link add link命令创建vlan子设备 ip link add link 命令用于在 Linux 系统中创建网络设备&#xff0c;其中可以用它来创建 VLAN (Virtual Local Area Network) 子接口&#xff0c;这是一个典型的用法。 VLAN是一种在二层网络&#xff08;即数据链路层&#xff09;上区分…

大模型开发Embedding技术介绍

什么是Embedding&#xff1f; 在自然语言处理&#xff08;NLP&#xff09;和机器学习中&#xff0c;Embedding 是一种将高维数据映射到低维连续空间的技术。Embedding 允许我们将词语、句子或其他类型的数据表示成向量&#xff0c;这些向量捕捉了数据的语义和上下文信息。 Em…

Vue3 头像是圆形,hover上去时头像出现黑色半透明样式,且中间显示修改两字的实现

实现效果 原头像 hover效果 实现方式 博主在实际开发过程中使用mouseover和mouseout会出现无法点击或hover频繁闪动的问题&#xff0c;故这里采用的是css中的hover&#xff0c;利用hover也能轻松实现上述效果&#xff0c;且完全不会影响点击事件的使用。 <template> &…

2024年燃气企业负责人和安全管理人员考试题库。

31.使用&#xff08; &#xff09;进行液化天然气(LNG)的输送&#xff0c;对于卸、装车可以缩短卸、装车时间&#xff0c;提高输送效率。 A.低温泵 B.增压器 C.减压器 答案:A 32.液化天然气(LNG)用作调峰气源时&#xff0c;应注意与原燃气的&#xff08; &#xff09;&…

【Unity】AssetBundle打包策略

【Unity】AssetBundle打包策略 在游戏开发过程中&#xff0c;AssetBundle(AB)打包策略的重要性不容忽视。游戏开发者往往手动设置游戏资源包名进行管理&#xff0c;难免会造成资源确实或导致冗余&#xff0c;因此对于AB包的打包流程来说&#xff0c;进行策略管理显得十分重要。…