c++如何实现Prim算法最小生成树_c++ 邻接矩阵与贪心策略选择【实战】
发布时间 - 2025-12-29 00:00:00 点击率:次Prim算法用邻接矩阵实现需初始化key[0]=0、其余INT_MAX,每次选未入树且key最小的顶点u,再更新其邻接点v的key和parent;贪心正确性源于MST切割性质,支持负权边,时间复杂度O(n²),稠密图适用,但需避免0误判无边、索引错位及状态残留。
Prim算法在C++中用邻接矩阵怎么写
邻接矩阵是Prim算法最直观的实现方式,尤其适合顶点数不多(比如 n ≤ 1000)的稠密图。核心思路是维护一个key[]数组记录每个顶点到当前生成树的最小边权,再用inMST[]标记是否已加入生成树。
关键点不是“能不能写”,而是初始化和更新逻辑容易出错:比如key[0]必须设为0(从顶点0开始),其余初始化为INT_MAX;每次选key最小且未入树的顶点时,必须检查!inMST[u],否则会重复选取。
vector> graph = { {0, 2, 0, 6, 0}, {2, 0, 3, 8, 5}, {0, 3, 0, 0, 7}, {6, 8, 0, 0, 9}, {0, 5, 7, 9, 0} }; int n = graph.size(); vector key(n, INT_MAX); vector inMST(n, false); vector parent(n, -1); key[0] = 0; for (int i = 0; i < n; i++) { int u = -1; for (int j = 0; j < n; j++) if (!inMST[j] && (u == -1 || key[j] < key[u])) u = j; inMST[u] = true; for (int v = 0; v < n; v++) if (graph[u][v] != 0 && !inMST[v] && graph[u][v] < key[v]) { key[v] = graph[u][v]; parent[v] = u; } }
为什么贪心选择“当前最小边”不会错过全局最优
Prim的贪心正确性依赖于MST的切割性质(cut property):对任意切割,横跨该切割的最小权重边一定属于某棵MST。算法每一步都在维护一个已构建的子树集合S,把V\S看作另一侧——此时连接S与V\S的最小边必然可安全加入。
- 这个性质不依赖边权是否为正,但要求图连通;若不连通,
key[v]最终仍为INT_MAX,可据此判断 - 如果图含负权边,Prim依然成立(不同于Dijkstra),因为不涉及路径累加,只比单条边权
- 但邻接矩阵中用
0表示无边时,必须确保真实边权≠0;否则要改用-1或INT_MAX作无效标记
邻接矩阵Prim的时间复杂度和优化边界
标准实现是O(n²):外层循环n次,每次找最小key耗O(n),更新邻居也耗O(n)。这比堆优化版(O(m log n))在稀疏图中慢,但在稠密图(m ≈ n²)下两者接近,且邻接矩阵常数更小、代码更稳。
真正要注意的是内存和初始化开销:
-
graph二维vector大小为n × n,n=10⁴时就需约
400MB内存(int占4字节),直接爆掉 - 若实际边数很少,强行用邻接矩阵纯属浪费;应切到邻接表+priority_queue
- 初始化
key用vector没问题,但别用(n, INT_MAX) memset(key, 0x3f, sizeof(key))——它按字节赋值,对int可能不等于0x3f3f3f3f
调试时最常见的三个错误现象
写完跑不对?先盯这三个地方:
- 邻接矩阵中用
0表示“无边”,但某条合法边权恰好是0 → 更新时if (graph[u][v] != 0)会跳过它。解决:统一用-1或INT_MAX作无效标记,或额外存valid标志 -
parent[v] = u写成parent[u] = v→ 最终输出的边反向,生成树结构错乱 - 没重置
inMST或key就复用同一组变量跑多组数据 → 上一轮残留状态污染结果
邻接矩阵Prim看似简单,但初始化语义、无效值约定、索引方向这三点,几乎包揽了90%的本地调试失败原因。
# 字节
# c++
# 为什么
# if
# int
# 循环
# 堆
# Property
# 算法
# 子树
# 的是
# 都在
# 不多
# 设为
# 但在
# 要注意
# 时就
# 再用
# 这三个
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
详解jQuery中的事件
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
Laravel如何为API生成Swagger或OpenAPI文档
Laravel Docker环境搭建教程_Laravel Sail使用指南
Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】
js代码实现下拉菜单【推荐】
夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化
jQuery validate插件功能与用法详解
Laravel如何处理CORS跨域请求?(配置示例)
Laravel如何与Docker(Sail)协同开发?(环境搭建教程)
java中使用zxing批量生成二维码立牌
Laravel如何使用Eloquent ORM进行数据库操作?(CRUD示例)
Android仿QQ列表左滑删除操作
Android实现代码画虚线边框背景效果
如何用5美元大硬盘VPS安全高效搭建个人网站?
如何快速生成专业多端适配建站电话?
香港服务器建站指南:外贸独立站搭建与跨境电商配置流程
详解阿里云nginx服务器多站点的配置
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?
韩国服务器如何优化跨境访问实现高效连接?
高配服务器限时抢购:企业级配置与回收服务一站式优惠方案
Laravel怎么连接多个数据库_Laravel多数据库连接配置
如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】
如何获取PHP WAP自助建站系统源码?
UC浏览器如何切换小说阅读源_UC浏览器阅读源切换【方法】
如何在IIS中新建站点并配置端口与物理路径?
晋江文学城电脑版官网 晋江文学城网页版直接进入
如何用虚拟主机快速搭建网站?详细步骤解析
Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程
Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】
INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】
Python并发异常传播_错误处理解析【教程】
JavaScript中的标签模板是什么_它如何扩展字符串功能
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法
教学论文网站制作软件有哪些,写论文用什么软件
?
laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析
Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程
如何用wdcp快速搭建高效网站?
SQL查询语句优化的实用方法总结
原生JS实现图片轮播切换效果
浅析上传头像示例及其注意事项
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
JavaScript模板引擎Template.js使用详解
如何自定义建站之星模板颜色并下载新样式?
Laravel如何为API编写文档_Laravel API文档生成与维护方法


400MB内存(int占4字节),直接爆掉