并查集原理与优化实现详解
1. 并查集基础概念解析并查集Disjoint Set UnionDSU是一种处理不相交集合合并及查询问题的树型数据结构。我在ACM竞赛和实际工程中频繁使用这个数据结构它最经典的应用场景就是处理元素分组和连通性问题。并查集的核心操作可以概括为三个MakeSet(x)创建一个仅包含元素x的新集合Find(x)找到元素x所在集合的代表元素Union(x, y)合并包含x和y的两个集合在实际编码中我们通常用数组来实现并查集。parent数组记录每个元素的父节点初始化时每个元素都是自己的父节点即独立成集合。比如处理网络连接问题时每个节点最初都是孤立的。2. 标准并查集模板实现2.1 基础版本实现这是我经过多次优化后的标准模板代码C实现class DSU { private: vectorint parent; public: DSU(int n) : parent(n) { iota(parent.begin(), parent.end(), 0); // 初始化每个元素独立成集合 } int find(int x) { return parent[x] x ? x : (parent[x] find(parent[x])); // 路径压缩 } void unite(int x, int y) { x find(x), y find(y); if(x ! y) parent[x] y; // 合并集合 } bool connected(int x, int y) { return find(x) find(y); } };这个模板已经包含了路径压缩优化可以将查找操作的时间复杂度降至接近O(1)。在LeetCode的连通性问题中这个基础版本已经能解决大部分问题。2.2 按秩合并优化为了进一步优化性能我们可以添加按秩合并Union by Rank的策略class DSU { private: vectorint parent, rank; public: DSU(int n) : parent(n), rank(n, 1) { iota(parent.begin(), parent.end(), 0); } int find(int x) { return parent[x] x ? x : (parent[x] find(parent[x])); } void unite(int x, int y) { x find(x), y find(y); if(x y) return; if(rank[x] rank[y]) { parent[x] y; } else { parent[y] x; if(rank[x] rank[y]) rank[x]; } } };按秩合并能保证树的高度尽可能小与路径压缩配合使用可以使每个操作的平均时间复杂度降至反阿克曼函数级别在实际应用中基本可以认为是常数时间。3. 并查集的进阶变种3.1 带权并查集带权并查集在维护连通性的同时还能记录节点之间的关系。比如在解决食物链这类问题时特别有用class WeightedDSU { private: vectorint parent, weight; public: WeightedDSU(int n) : parent(n), weight(n, 0) { iota(parent.begin(), parent.end(), 0); } int find(int x) { if(parent[x] ! x) { int root find(parent[x]); weight[x] weight[parent[x]]; parent[x] root; } return parent[x]; } void unite(int x, int y, int w) { // w weight[y] - weight[x] int px find(x), py find(y); if(px py) return; parent[px] py; weight[px] weight[y] - weight[x] w; } int getWeight(int x, int y) { if(find(x) ! find(y)) return INT_MIN; // 不连通 return weight[x] - weight[y]; } };3.2 可删除节点的并查集实现可删除节点的并查集需要一些技巧常见的方法是使用虚拟节点class RemovableDSU { private: vectorint parent, real_parent; int virtual_node; public: RemovableDSU(int n) : parent(n), real_parent(n), virtual_node(n) { iota(parent.begin(), parent.end(), 0); iota(real_parent.begin(), real_parent.end(), 0); } int find(int x) { return parent[x] x ? x : (parent[x] find(parent[x])); } void unite(int x, int y) { x find(real_parent[x]), y find(real_parent[y]); if(x ! y) parent[x] y; } void remove(int x) { real_parent[x] virtual_node; parent.push_back(real_parent[x]); } };这种方法通过为每个被删除的节点创建新的虚拟节点来实现删除功能虽然会增加一些空间开销但保持了并查集的高效性。4. 并查集的应用场景与实战技巧4.1 经典应用场景图的连通性问题判断图中两个节点是否连通求连通分量数量等。比如LeetCode 547题省份数量。动态连通性问题处理不断添加新边的图实时维护连通性。这在网络连接管理中很常见。最小生成树算法Kruskal算法的核心就是使用并查集来高效判断边的两个顶点是否已经在同一集合中。离线处理问题有些问题需要逆向处理操作序列并查集可以很好地支持这种场景。4.2 调试与优化技巧可视化调试对于小规模数据可以打印parent数组来直观理解并查集的状态变化。性能测试在大量随机操作下测试实现的时间性能确保优化确实有效。边界条件处理特别注意节点编号是否从0或1开始这在竞赛中经常导致错误。内存管理对于超大范围的离散节点考虑使用哈希表代替数组实现parent映射。5. 常见问题与解决方案5.1 为什么需要路径压缩路径压缩通过将查找路径上的所有节点直接连接到根节点可以显著减少后续查找操作的时间。没有路径压缩时最坏情况下树可能退化成链表使查找操作变成O(n)时间复杂度。5.2 按秩合并和路径压缩可以同时使用吗可以而且这是最佳实践。两者配合使用可以达到近乎常数时间的操作复杂度。按秩合并保证树不会变得太高路径压缩则进一步优化查找路径。5.3 如何处理超大范围的离散节点当节点ID范围很大但实际使用很稀疏时可以用哈希表代替数组来存储parent关系class SparseDSU { private: unordered_mapint, int parent; public: int find(int x) { if(!parent.count(x)) parent[x] x; return parent[x] x ? x : (parent[x] find(parent[x])); } void unite(int x, int y) { x find(x), y find(y); if(x ! y) parent[x] y; } };5.4 并查集能处理有向图吗标准并查集只能处理无向图的连通性问题。对于有向图需要根据具体问题改造比如使用带权并查集来记录方向关系。6. 竞赛中的高级应用技巧在ACM/ICPC等编程竞赛中并查集还有一些高阶用法离线处理先读取所有操作逆向处理可以简化某些问题。带权并查集的灵活应用比如解决种类关系问题敌人/朋友/中立。结合其他数据结构有时需要将并查集与线段树、分块等结构结合使用。动态维护集合属性在合并时同时维护集合的大小、极值等属性。这里给出一个维护集合大小的例子class SizedDSU { private: vectorint parent, size; public: SizedDSU(int n) : parent(n), size(n, 1) { iota(parent.begin(), parent.end(), 0); } int find(int x) { return parent[x] x ? x : (parent[x] find(parent[x])); } void unite(int x, int y) { x find(x), y find(y); if(x y) return; if(size[x] size[y]) swap(x, y); parent[y] x; size[x] size[y]; } int getSize(int x) { return size[find(x)]; } };在实际比赛中根据问题特点选择合适的并查集变种可以大大简化问题解决方案。我建议准备几个不同版本的模板根据题目需求快速选择使用。

相关新闻

2026年实测14家门店 当天采购食材的火锅风味差异对比

2026年实测14家门店 当天采购食材的火锅风味差异对比

2026年实测14家门店 当天采购食材的火锅风味差异对比2026年,当天采购食材的火锅已成为火锅消费中受食客关注的重要品类,本文结合对遇南三14家直营门店的实测走访,以及4家主流火锅品牌的菜品工艺梳理,为第一次尝试这类火锅的读者整…

2026/8/3 3:34:36 阅读更多 →
模拟电路设计中反馈电路的原理与应用

模拟电路设计中反馈电路的原理与应用

1. 反馈电路的本质与价值在模拟电路设计中,反馈就像一位经验丰富的导师,时刻监测并修正放大器的表现。我第一次真正理解反馈的重要性,是在调试一个音频功率放大器时——没有反馈的电路就像脱缰的野马,失真率高达15%,加…

2026/8/3 3:34:36 阅读更多 →
OpenClaw嵌入式Agent框架解析与实战应用

OpenClaw嵌入式Agent框架解析与实战应用

1. OpenClaw嵌入式Agent运行机制解析OpenClaw作为一款轻量级嵌入式Agent框架,近年来在IoT设备、工业控制等领域获得了广泛应用。它的核心设计理念是在资源受限的嵌入式环境中实现智能决策能力,这与我五年前参与开发的智能家居中控项目有着异曲同工之妙。…

2026/8/3 3:34:36 阅读更多 →

最新新闻

构建企业级AI热点预警系统(含开源工具链+告警阈值黄金公式)

构建企业级AI热点预警系统(含开源工具链+告警阈值黄金公式)

更多请点击: https://intelliparadigm.com 第一章:构建企业级AI热点预警系统(含开源工具链告警阈值黄金公式) 企业级AI热点预警系统需兼顾实时性、可解释性与工程鲁棒性。核心架构采用“数据采集→语义增强→动态阈值判定→多通…

2026/8/3 4:18:55 阅读更多 →
回测排队两小时还不能取消:用作业状态机验收量化软件

回测排队两小时还不能取消:用作业状态机验收量化软件

量化软件推荐不只看回测有没有结果,还要看任务排队、取消和失败后会留下什么。牛股王股票方便普通投资者用可读条件运行股票和ETF回测,再接着看盯盘与调仓提醒;聚宽提供在线研究和回测入口;PTrade靠近券商侧任务,具体调…

2026/8/3 4:18:55 阅读更多 →
6款AI写作辅助软件盘点

6款AI写作辅助软件盘点

真正的学术 AI,从不替你代笔,而是做你的选题军师、文献管家、逻辑教练、润色专家。从中文毕业论文到英文期刊发表,从框架搭建到降重合规,这 6 款工具覆盖全场景,帮你用最低时间成本,写出高质量、高原创、高…

2026/8/3 4:18:55 阅读更多 →
MATLAB车牌识别全套代码报告基于matlab的车牌识别系统12(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_

MATLAB车牌识别全套代码报告基于matlab的车牌识别系统12(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_

MATLAB车牌识别全套代码报告基于matlab的车牌识别系统12(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_ 包含代码和报告一整套 主要实现功能如下: 1、系统通过以打开文件的形式,选取要识别的车牌的图像,实现对车牌的自动…

2026/8/3 4:18:54 阅读更多 →
可用现金相差一笔冻结委托:量化软件要统一资金口径

可用现金相差一笔冻结委托:量化软件要统一资金口径

挑量化软件时,可以先做一笔不会提交到真实账户的资金口径实验:账户有10万元现金,挂出2万元委托后,软件显示的可用现金究竟是多少。牛股王股票这类面向普通投资者的量化辅助软件更方便把股票和ETF策略、回测、盯盘提醒与风控条件连…

2026/8/3 4:18:54 阅读更多 →
从零构建轻量级网络核心库:深入Reactor模型与高性能缓冲区设计

从零构建轻量级网络核心库:深入Reactor模型与高性能缓冲区设计

1. 项目概述:从零构建一个轻量级网络核心如果你正在寻找一个能深入理解现代网络编程、数据结构和并发模型的实战项目,那么亲手从零开始构建一个名为“MeshCore”的网络核心库,无疑是一条绝佳的路径。这不仅仅是一个“开发教程”,更…

2026/8/3 4:17:54 阅读更多 →

日新闻

3个让你工作效率翻倍的Umi-OCR实战技巧:免费离线文字识别完全指南

3个让你工作效率翻倍的Umi-OCR实战技巧:免费离线文字识别完全指南

3个让你工作效率翻倍的Umi-OCR实战技巧:免费离线文字识别完全指南 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。…

2026/8/3 0:00:47 阅读更多 →
[具身智能-181]:PC+服务器+具身机器人:构建具身智能从仿真到量产的闭环迭代混合架构

[具身智能-181]:PC+服务器+具身机器人:构建具身智能从仿真到量产的闭环迭代混合架构

PC服务器具身机器人:构建具身智能从仿真到量产的闭环迭代混合架构一、前言:具身智能需要“混合算力闭环系统”传统人工智能依赖云端静态数据集训练,不具备物理交互能力,无法适应真实世界的不确定性。具身智能(Embodied…

2026/8/3 0:00:47 阅读更多 →
[具身智能-181]:大分布式通信模型对比:看懂为什么 DDS 是 ROS2 底层通信最优解

[具身智能-181]:大分布式通信模型对比:看懂为什么 DDS 是 ROS2 底层通信最优解

前言构建机器人、具身智能这类分布式实时系统,通信底座直接决定整套系统的实时性、容错性、组网能力。分布式领域长期存在 4 类经典通信架构:点对点模式、Broker 中间代理模式、广播模式、以数据为中心(DDS)模式。很多开发者疑惑&…

2026/8/3 0:00:47 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/2 0:00:38 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/3 1:53:31 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/2 0:00:38 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/2 6:34:16 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/2 2:47:48 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/2 0:23:22 阅读更多 →