C++最小生成树Kruskal算法怎么配合并查集写

梦墨同学_3226

梦墨同学_3226

2026-10-01

248人浏览

原创

kruskal算法必须使用带路径压缩和按秩合并的并查集,因其是唯一能高效判断连通性与动态合并连通分量的基础设施;裸并查集在边数达10⁵时易tle或wa。

c++最小生成树kruskal算法怎么配合并查集写

直接说结论: Kruskal 算法必须配合并查集(Union-Find)才能高效判断环、合并连通分量;不带路径压缩和按秩合并的裸 find/union 在稀疏图上可能 TLE 或 WA,尤其边数接近 10⁵ 时。

为什么非得用并查集?——不是“能用”,是“绕不开”

Kruskal 的核心逻辑是:从小到大取边,只加“连接两个不同连通块”的边。问题来了——怎么快速知道两个顶点 u 和 v 是否已连通?

  • 暴力 DFS/BFS 每次判连通:O(V+E) × 边数 → 肯定超时
  • 邻接矩阵维护连通性:O(V²) 空间 + 每次合并要刷整行/列 → 不现实
  • 并查集:单次 find 平均 O(α(V)),union 同样极快,且天然支持动态合并

换句话说,并查集不是“辅助工具”,它是 Kruskal 正确性和效率的基础设施。

关键函数怎么写?——find 必须带路径压缩,unionSet 建议加按秩合并

常见错误是写一个只递归不压缩的 find,导致深度退化成链表,最坏 O(n);或者 union 盲目挂树,让树越来越高。

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载
  • find(x):用循环或递归找到根,**同时把路径上所有节点父指针直连根**(路径压缩)
  • unionSet(u, v):先 find(u) 和 find(v),若根不同才合并;推荐用 rank 数组控制谁挂谁(小树挂大树),避免深度暴涨
  • 初始化:father[i] = i,rank[i] = 0(或全 1,看实现习惯)

示例片段(C++):

int find(int x) {
    return father[x] == x ? x : father[x] = find(father[x]); // 递归+路径压缩
}
void unionSet(int u, int v) {
    u = find(u), v = find(v);
    if (u == v) return;
    if (rank[u] <h3>边排序和主循环怎么组织?——别漏判“无法生成树”的情况</h3><p>排序本身简单,但要注意两点:一是结构体数组 + <code>sort</code> 或 <code>qsort</code>;二是主循环里必须统计加入的边数,不能只靠遍历完所有边就结束。</p>
  • 边存为结构体:struct Edge { int u, v, w; };,重载 operator 或写 <code>cmp 函数
  • 主循环终止条件是 edges_used == n - 1,不是 i ;提前 break 更安全
  • 循环结束后检查:if (edges_used != n - 1) return -1;(说明图不连通,无 MST)
  • 权值累加放在 unionSet 成功后,别放错位置

容易被忽略的细节:索引从 0 还是 1 开始?rank 初始值填多少?

这直接导致越界或逻辑错误,但很多人调试半天才发现。

  • 如果顶点编号是 1~n,father 和 rank 数组大小至少为 n+1,下标 0 不用也得留空
  • rank 初始全 0 是标准做法(表示单节点树高度为 0);填 1 也可以,但 union 逻辑要同步改,否则 rank[u] == rank[v] 判断失效
  • 输入边时注意方向无关性:无向图中 (u,v) 和 (v,u) 等价,但并查集不关心方向,只要两端点正确即可
  • 边权为 0 或负数?Kruskal 仍适用,排序和比较逻辑不变

真正卡住人的往往不是算法思想,而是 father 数组开小了、find 忘了赋值、或者 unionSet 里没先 find 就直接操作原节点。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2208

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

979

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

407

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

307

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

386

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

580

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1389

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1197

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1305

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习