Prim最小生成树算法

news/2025/1/19 16:39:50/文章来源:https://www.cnblogs.com/dianman/p/18679691

Prim最小生成树算法

首先给出最小生成树的概念:把给定的无向图中转换成一棵树,且树的边权和最小

Prim算法基于贪心的思想,每次在图中选取距离最小生成树最近的点加入树

首先给出朴素的模板算法:

struct edge{int v,w;
};int n,m;
vector<edge> e[5010];
int dis[5010];
bool vis[5010];
int cnt,sum;void init(void){memset(dis,0x3f,sizeof dis);
}bool prim(int s){init();dis[s]=0;while(1){int u=0;for (int i=1;i<=n;i++){if (dis[i]<dis[u]&&!vis[i])u=i;}if (u==0) break;vis[u]=1;cnt++;sum+=dis[u];for (auto it=e[u].begin();it!=e[u].end();it++){if (dis[it->v]>it->w)dis[it->v]=it->w;}}return cnt==n;
}

其中的

int u=0;
for (int i=1;i<=n;i++){if (dis[i]<dis[u]&&!vis[i])u=i;
}
if (u==0) break;

作用是找到一个距离最小生成树最近的点(这个点还没有加入树)

如果最后没有找到满足条件的点,就应该结束循环,退出 while(1)

vis[u]=1;//标记找到的这个点已经被加入树中
cnt++;//记录加入树的节点数加一
sum+=dis[u];//最小生成树的边权和

然后根据找到的这个点更新它连通的邻点到最小生成树的距离

for (auto it=e[u].begin();it!=e[u].end();it++){if (dis[it->v]>it->w)dis[it->v]=it->w;
}

这里以一个连通图为例:

我们可以任意以一个点为 s 即起始点,s=1

第一轮:

树无节点,此时的disdis[]={inf,0,inf,inf,inf},从小到大找到 1 为最小点,1 加入最小生成树

然后更新 1 的邻点,dis={inf,0,2,2,6}

第二轮:

树节点有 1,此时的disdis[]={inf,0,2,2,6},从小到大找到 2 为最小点,2 加入最小生成树

然后更新 2 的邻点,dis={inf,0,2,2,6}

第三轮:

树节点有 1,2,此时的disdis[]={inf,0,2,2,6},从小到大找到 3 为最小点,3 加入最小生成树

然后更新 3 的邻点,dis={inf,0,2,2,3}

第三轮:

树节点有 1,2,3,此时的disdis[]={inf,0,2,2,3},从小到大找到 4 为最小点,4 加入最小生成树

然后更新 4 的邻点,dis={inf,0,2,2,3}

第四轮:

树节点有 1,2,3,4,此时的disdis[]={inf,0,2,2,3},找不到满足条件的点,退出循环

return cnt==n;

返回所有的点是否都加入了树,如果没有全部进树,说明存在不连通点

同样的,对于找最近点的操作可以使用 priority_queue 优先队列优化

priority_queue<pair<int,int>> q;bool prim(int s){init();dis[s]=0;q.push({0,s});while (q.size()){auto t=q.top();q.pop();if (vis[t.second]) continue;vis[t.second]=1;sum-=t.first;cnt++;for (auto it=e[t.second].begin();it!=e[t.second].end();it++){if (dis[it->v]>it->w){dis[it->v]=it->w;q.push({-dis[it->v],it->v});}}}return cnt==n;
}

使用优先队列优化后仍然不要忘记判断点和树的关系

if (vis[t.second]) continue;//如果不是没有进树的点,那就重新找

区别于最短路的问题,最小生成树更新边的关系原理不一样

for (auto it=e[u].begin();it!=e[u].end();it++){//此时的u已经进了树if (dis[it->v]>it->w)//到树的距离为dis[v]和wdis[it->v]=it->w;//取两者最小,即更新最短距离
}

在最小生成树中,把边权重新更新为 到树的最短距离,而非最短路中的到起始点的最短距离

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/871755.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

同余前缀和

1 #include<iostream>2 using namespace std;3 4 /*5 原题地址:https://www.luogu.com.cn/problem/P31316 农夫约翰的 \( N \) 头奶牛站在一排,就像它们时不时做的那样。每头奶牛都有一个唯一的整数ID号,7 这样农夫约翰可以区分它们。农夫约翰想要给一组连…

1.MySql基础架构之SQL语句的执行

1.MySQL数据库的整体架构(i)连接器:连接器负责与客户端建立连接,获取权限、维持和管理连接。连接命令中的mysql是客户端工具,用来建立服务端连接。在完成经典的TCP握手后,连接器就要开始认证你的身份,这个时候用的就是你输入的用户名和密码。 ​ 如果用户名密码认证通过…

ATF引导启动流程整理-Part2:BL1引导启动流程整理

接上一章的介绍,本文详细整理一下 BL1 阶段的流程 Ch3: ATF启动流程 上面一章简单的介绍了 ATF的隔离和划分,下面就介绍一下使用 ATF 初始启动的流程。ARM v8的启动流程包含多个阶段,典型的官方定义的标志阶段包括 BL1、BL2、BL31、BL32、BL33,根据不同需求这些阶段可以添加…

推荐一款非常好用的在线 SSH 管理工具

前言 SSH工具在远程连接、文件传输、远程管理和增强安全性等方面发挥着重要作用,是我们开发人员和系统管理员不可或缺的工具。今天大姚给大家推荐一款非常好用的在线 SSH 管理工具:Xterminal。工具介绍 Xterminal一个好用的在线SSH、SFTP工具,支持跨平台(Windows、Linux、M…

代码随想录——动态规划背包问题总结

https://www.programmercarl.com/背包总结篇.html#听说背包问题很难-这篇总结篇来拯救你了

DASCTF --wp--web

1、Rank-lSsti的报错查询cycler没用被禁用,很常规的到达popen阶段{{cycler.__init__.__globals__.__builtins__[__import__](os).popen(ls).read()}}正常在浏览器中无法查看,使用pythonimport requestswith requests.Session() as session: url_phone = http://139.155.12…

动态规划——26单词拆分

这道题用代码随想录的解释有点牵强,第二层for循环和递推公式也没有说明白。代码 class Solution { public:bool wordBreak(string s, vector<string>& wordDict) {unordered_set<string> set(wordDict.begin(),wordDict.end());//字典单词是物品,s是背包int …

使用Wireshark抓包工具

下载Wireshark: https://www.wireshark.org/ 选择要监听的网卡 用户界面数据包分层结构关于过滤器 分为 显示过滤器 和 捕获过滤器 显示过滤器:过滤已捕获的数据包,符合条件的进行显示 ip.addr == ip地址 # 过滤所有与该网站相关的数据包ip.addr == ip地址 && http …

【NodeJS渗透】提取和分析.asar文件的案例研究

免责声明 ⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权!硬编码密钥(在SQLite中)和加密算法(在AesFormula.js文件中)信息泄露导致真实凭据被泄露 一、案例研究 本节案…

Spring,Spring Ioc,Bean详解

Spring框架Spring框架是Java应用最广的框架,其的成功来自于理念,并非是技术,其中几个理念非常重要,例如IoC(控制反转),AOP(面向切面编程)Spring的优势低耦合/低侵入(解耦)Spring通过IoC(控制反转)和DI(依赖注入)来实现低耦合高内聚声明式事务管理Spring基于AOP的方式,使其能够在…

远程桌面键盘记录器

针对远程桌面协议 (RDP) 相关进程的击键记录器,它利用键盘输入挂钩,允许其记录某些上下文中的击键(例如在 mstsc.exe 和 CredentialUIBroker.exe 中) 使用vs直接编译就可以了运行TakeMyRDP.exe打开mstsc,输入ip地址,输入账号密码密码直接显示出来,这个exe不需要高权限运行…

【nginx】Nginx重定向方法

Nginx重定向配置是一个功能强大且灵活的工具,可以根据具体需求实现各种重定向规则。 以下是对Nginx请求重定向配置方法的详细解析:1、基本概念 请求重定向是指当客户端向服务器发送一个请求时,服务器根据一定的规则将客户端的请求引导到另外一个URL的过程。在Nginx中,通过r…