新闻中心
C++如何实现一个最小生成树算法_C++图论之Prim与Kruskal算法详解
Prim算法从点出发,每次选最近顶点加入生成树,适合稠密图;Kruskal按边权排序贪心选取,用并查集判环,适合稀疏图;两者时间复杂度分别为O(V²)和O(E log E),应根据图的密度选择。

在图论中,最小生成树(Minimum Spanning Tree, MST)是连接无向连通图中所有顶点的一棵树,且边的权值总和最小。C++中常用的两种求解MST的算法是Prim算法和Kruskal算法。下面详细介绍它们的原理与实现方式。
Prim算法:从点出发构建最小生成树
Prim算法的核心思想是从一个起始顶点开始,逐步扩展生成树,每次选择与当前生成树相连且权值最小的边所连接的新顶点,直到覆盖所有顶点。
适用场景:稠密图(边数接近顶点数平方),使用邻接矩阵存储更高效。
Prim算法步骤:
- 初始化一个布尔数组visited标记顶点是否已加入生成树,距离数组dist记录各顶点到生成树的最短距离
- 从任意起点(如0号顶点)开始,更新其邻接点的距离
- 每次从未访问顶点中选出dist最小的顶点u,将其加入生成树
- 用u更新其所有邻接点的距离
- 重复上述过程直到所有顶点都被访问
代码实现(邻接矩阵):
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
<p>const int INF = INT_MAX;</p><p>int prim(vector<vector<int>>& graph, int n) {
vector<int> dist(n, INF);
vector<bool> visited(n, false);
dist[0] = 0;
int totalWeight = 0;</p><pre class='brush:php;toolbar:false;'>for (int i = 0; i < n; i++) {
int u = -1;
for (int j = 0; j < n; j++) {
if (!visited[j] && (u == -1 || dist[j] < dist[u]))
u = j;
}
if (dist[u] == INF) return -1; // 图不连通
visited[u] = true;
totalWeight += dist[u];
for (int v = 0; v < n; v++) {
if (graph[u][v] != 0 && !visited[v] && graph[u][v] < dist[v]) {
dist[v] = graph[u][v];
}
}
}
return totalWeight;}
Kruskal算法:按边排序贪心选取
Kruskal算法基于贪心策略,将所有边按权值从小到大排序,依次尝试加入生成树,若加入后不形成环,则保留该边,否则跳过。
适用场景:稀疏图(边较少),使用边列表存储效率更高。
Kruskal算法关键点:
CA.LA
第一款时尚产品在线设计平台,服装设计系统
94
查看详情
- 需要对边进行排序
- 使用并查集(Union-Find)判断是否形成环
- 当加入n-1条边时,生成树完成
代码实现:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
<p>struct Edge {
int u, v, weight;
bool operator<(const Edge& other) const {
return weight < other.weight;
}
};</p><p>class UnionFind {
vector<int> parent;
public:
UnionFind(int n) {
parent.resize(n);
for (int i = 0; i < n; i++) parent[i]
= i;
}</p><pre class='brush:php;toolbar:false;'>int find(int x) {
if (parent[x] != x)
parent[x] = find(parent[x]);
return parent[x];
}
void unite(int x, int y) {
parent[find(x)] = find(y);
}
bool connected(int x, int y) {
return find(x) == find(y);
}};
int kruskal(vector
for (const Edge& e : edges) {
if (!uf.connected(e.u, e.v)) {
uf.unite(e.u, e.v);
totalWeight += e.weight;
edgesAdded++;
if (edgesAdded == n - 1) break;
}
}
return edgesAdded == n - 1 ? totalWeight : -1; // 不连通返回-1}
两种算法对比与选择建议
理解两者差异有助于在实际问题中做出合适选择。
时间复杂度比较:
- Prim(邻接矩阵):O(V²),适合顶点少、边多的情况
- Prim(优先队列优化):O(E log V),适用于稀疏图
- Kruskal:O(E log E),主要开销在排序,适合边较少的图
空间复杂度:
- Prim通常使用邻接矩阵或邻接表,空间O(V²)或O(E)
- Kruskal只需存储边列表,空间O(E)
选择建议:
- 图很稠密(比如完全图)→ 优先考虑Prim
- 图较稀疏或边已以列表形式给出 → Kruskal更直观高效
- 需要频繁添加/删除边 → Kruskal更容易维护
基本上就这些。两种算法都能正确求出最小生成树,关键是根据数据规模和结构选择合适的方法。实际编程中注意处理图不连通的情况,避免无限循环或错误结果。
以上就是C++如何实现一个最小生成树算法_C++图论之Prim与Kruskal算法详解的详细内容,更多请关注其它相关文章!
# 管理机制
# 食品网站推广便宜
# 郑州seo效果评估
# seo优化pc端
# seo岗位所需技能
# 万江抖音seo流程
# 重庆360推广营销案例
# 40岁还能学seo吗
# 长春seo逻辑查询
# 长安搜索矩阵seo
# 开发区网站优化团队建设
# 复用
# 多路
# go
# 何为
# 较少
# 求出
# 图论
# 都是
# 两种
# 如何实现
# stream
# ios
# c++
# edge
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
sublime如何只显示或隐藏特定类型文件_sublime侧边栏文件过滤
我的世界mc.js免费游戏直接能玩 我的世界mc.js小游戏免费秒玩入口
AO3官方镜像站点汇总 AO3同人作品网页版直达链接
Node.js CSV 数据处理:基于字段值条件过滤整条记录的策略
mc.js游戏直达 mc.js网页免下载版本秒进地址
厨房不锈钢水槽发黑生锈怎么处理_水槽用可乐+锡纸2分钟抛亮如新
优化 Python 函数中的条件逻辑:解决 if-else 嵌套与参数选择问题
c++ 命名空间怎么用 c++ namespace使用指南
狙击外星人小游戏开始_狙击外星人小游戏立即开始
Python实时数据流中的动态最值查找策略
漫蛙漫画官方主页入口 漫蛙MANWA网页直达访问链接
React/Next.js中实现列表项的动态选择与移动
Sublime怎么配置Nim语言环境_Sublime Nim代码高亮与补全
抖音创作助手登录入口_抖音创作辅助工具官网直达
Golang如何使用net/url解析URL_Golang URL解析与处理方法
天猫2025双十一0点秒杀攻略 天猫爆款抢购时间
文心一言怎样用插件调度API数据_文心一言用插件调度API数据【API调用】
SteamMachine定价或为699美元 大家想入手吗?
在Blazor WebAssembly应用中动态注入客户端特定指标代码的策略
mysql如何设置表访问权限_mysql表访问权限配置
12306选座怎么选到商务座_12306商务座选择与配置说明
《刺客信条4:黑旗》重制版新细节曝光:无缝加载 地图更细致!
抓大鹅无需下载版 抓大鹅秒玩版入口
LINUX怎么设置定时任务_LINUX crontab配置教程
J*aScript实现单选按钮与关联输入框的联动禁用教程
Go语言HTML解析:利用Goquery精准获取指定元素内容
NRF24L01数据传输深度解析:解决大载荷接收异常与分包策略
2025俄罗斯Yandex最新入口 官方网站地址及浏览器下载指南
MAC怎么安装Homebrew包管理器_MAC为开发者和高级用户安装命令行工具
夸克浏览器桌面版同步不了书签怎么处理 夸克浏览器跨设备同步异常解决方案
Spring Boot内嵌服务器与J*a EE全栈特性:选择与部署策略
MAC怎么让Dock栏只显示当前运行的应用_MAC终端命令实现极简Dock栏
初次安装JDK时环境变量如何正确配置_J*A_HOME与PATH设置规则讲解
Windows电脑怎么截图最方便_系统自带截图工具的5种神仙用法【技巧】
俄罗斯Yandex搜索引擎入口_Yandex官网免登录一键访问
Python类型检查:优化关联可选属性的Mypy推断策略
Django通过AJAX异步上传图片并保存至模型的完整指南
使用Python高效删除Word宏并转换DOCM为DOCX格式
Golang如何使用bytes.Split分割字节切片_Golang bytes切片分割方法
菜鸟取件码是什么怎么查 最全查询渠道汇总
文本文档写html代码怎么运行_文本文档html代码运行步骤【教程】
如何高效处理PHP中的Excel数据导入导出?PortPHP/Spreadsheet助你轻松搞定!
漫蛙2在线漫画入口 漫蛙正版漫画网页版直达
C++如何进行游戏物理模拟_使用Box2D库为C++游戏添加2D物理效果
Pandas DataFrame:高效添加条件计算列
J*aScript中如何高效提取对象指定属性
蛙漫移动版在线看 蛙漫手机浏览器直达入口
深入理解J*a链表中的IPosition接口与使用
京东单号查询入口_京东快递订单追踪入口
优化LangChain文档加载与ChromaDB集成:解决多文档处理与分块问题


2025-11-21
浏览次数:次
返回列表
= i;
}</p><pre class='brush:php;toolbar:false;'>int find(int x) {
if (parent[x] != x)
parent[x] = find(parent[x]);
return parent[x];
}
void unite(int x, int y) {
parent[find(x)] = find(y);
}
bool connected(int x, int y) {
return find(x) == find(y);
}