当前位置: 首页 > news >正文

常见算法题型之并查集。附模板题+两道真题

并查集讲解,附模板题,两道真题(PTA,蓝桥杯)

并查集是一种专门处理不相交集合的动态合并与查询问题的数据结构,核心解决「两个元素是否属于同一集合」「合并两个集合」「统计连通分量数量」等连通性问题。优化后单次操作均摊时间复杂度接近 (O(1)),是算法竞赛中最高频的数据结构之一。

一、核心原理

并查集通过父节点数组表示集合关系:每个元素有一个父节点,集合的代表元是树的根节点(父节点指向自身),只要两个元素的根节点相同,就说明它们属于同一个集合。

它只包含两个核心操作:

  • 查找(Find):找到元素所属集合的根节点
  • 合并(Union):将两个不相交的集合合并为一个

二、基础实现

1. 初始化

初始状态下每个元素独立成一个集合,父节点指向自己。

constintN=1e5+10;intp[N];// 父节点数组// 初始化:编号从1到nfor(inti=1;i<=n;i++)p[i]=i;

2. 基础查找

递归向上遍历父节点,直到找到根节点。

intfind(intx){if(p[x]!=x)returnfind(p[x]);returnp[x];}

3. 基础合并

找到两个元素的根节点,若根不同则将一棵树挂到另一棵树上。

voidunite(inta,intb){intfa=find(a),fb=find(b);if(fa!=fb)p[fa]=fb;}

三、优化策略

基础版并查集在极端情况下会退化成链表,查找效率骤降。通过优化可以让操作效率接近常数。

路径压缩

核心思想:在查找过程中,把路径上所有节点的父节点直接指向根节点,让树结构扁平化,后续查找可以一步直达根节点。

实现只需要修改一行代码:

intfind(intx){if(p[x]!=x)p[x]=find(p[x]);// 路径压缩:当前节点直接连到根returnp[x];}

这是并查集最核心的优化,几乎零成本,做题时必加。

说明:仅路径压缩就足以应对绝大多数题目;

四、模板题:AcWing 836. 合并集合

836. 合并集合 - AcWing题库

题目描述

一共有n nn个数,编号1 ∼ n 1 \sim n1n,初始每个数各在一个集合中。
m mm个操作,分为两种:

  • M a b:合并a aab bb所在的集合,已在同一集合则忽略
  • Q a b:询问a aab bb是否在同一集合中

解题思路

并查集纯模板题,直接实现带路径压缩的并查集,按指令执行对应操作即可。

完整代码

#include<iostream>usingnamespacestd;constintN=1e5+9;intn,m,p[N];intfind(intx){if(p[x]!=x)p[x]=find(p[x]);returnp[x];}intmain(){cin>>n>>m;for(inti=1;i<=n;i++)p[i]=i;while(m--){charop;inta,b;cin>>op>>a>>b;if(op=='M'){p[find(a)]=find(b);}else{cout<<(find(a)==find(b)?"Yes\n":"No\n");}}return0;}

五、真题实战1:部落问题(PTA L2-024)

https://pintia.cn/problem-sets/994805046380707840/exam/problems/type/7

题目描述

社区中有多个小圈子,朋友的朋友属于同一个部落。统计互不相交的部落总数,以及查询任意两人是否同属一个部落。

解题思路

  1. 同一个小圈子的人属于同一部落,将圈子内所有元素合并到同一集合
  2. set统计所有出现过的编号,得到总人数
  3. 统计所有出现过的人的根节点数量,即为部落总数
  4. 查询时直接判断两人根节点是否相同

完整代码

#include<bits/stdc++.h>usingnamespacestd;constintN=1e4+9;intp[N];set<int>people;// 记录所有出现过的人intfind(intx){if(p[x]!=x)p[x]=find(p[x]);returnp[x];}intmain(){intn;cin>>n;for(inti=1;i<N;i++)p[i]=i;for(inti=0;i<n;i++){intk,first;cin>>k>>first;people.insert(first);introot=find(first);for(intj=1;j<k;j++){inty;cin>>y;people.insert(y);p[find(y)]=root;}}// 统计部落数量set<int>tribes;for(autox:people)tribes.insert(find(x));cout<<people.size()<<' '<<tribes.size()<<'\n';intq;cin>>q;while(q--){inta,b;cin>>a>>b;cout<<(find(a)==find(b)?"Y\n":"N\n");}return0;}

六、真题实战2:P16237 [蓝桥杯 2026 省 B] 应急布线

[P16237 蓝桥杯 2026 省 B] 应急布线 - 洛谷

题目描述

N NN台计算机通过M MM条残存网线连接,分裂为多个连通区域。添加最少的应急跳线让全网连通,且在跳线总数最少的前提下,让单台计算机接入的跳线数量的最大值尽可能小。
输出最少跳线数、单台最大跳线数的最小值。

解题思路

第一问:最少跳线数

经典结论:k kk个连通块连成整体,最少需要k − 1 k-1k1条跳线。用并查集统计连通块总数cnt,答案即为cnt-1

第二问:单台最大跳线数的最小值

分类讨论:

  1. cnt == 1:无需跳线,答案为 0

  2. cnt == 2:只需 1 条跳线,最大值为 1

  3. cnt >= 3:将连通块分为两类

    • 孤立点(大小为1的连通块):数量c1
    • 非孤立连通块(大小≥2):数量c2 = cnt - c1,总点数c3 = n - c1

    先将非孤立连通块连成链,消耗c2-1条跳线,占用2 × ( c 2 − 1 ) 2\times(c2-1)2×(c21)个接口,剩余可用接口c4 = c3 - 2*(c2-1)

    • c4 >= c1:所有孤立点可直接接在非孤立块上,每点仅1条线,最大值为1
    • c4 < c1:部分孤立点需要串联,会出现接2条线的节点,最大值为2

完整代码

#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+9;intp[N],sz[N];intfind(intx){if(p[x]!=x)p[x]=find(p[x]);returnp[x];}intmain(){intn,m;cin>>n>>m;for(inti=1;i<=n;i++){p[i]=i;sz[i]=1;}while(m--){intu,v;cin>>u>>v;intfu=find(u),fv=find(v);if(fu!=fv){p[fu]=fv;sz[fv]+=sz[fu];}}intcnt=0,c1=0;for(inti=1;i<=n;i++){if(find(i)==i){cnt++;if(sz[i]==1)c1++;}}if(cnt==1){cout<<"0 0";return0;}intans1=cnt-1;cout<<ans1<<' ';if(cnt==2){cout<<1;return0;}intc2=cnt-c1;intc3=n-c1;intc4=c3-2*(c2-1);cout<<(c4>=c1?1:2);return0;}

七、总结

并查集是连通性问题的首选数据结构,核心要点:

  1. 两个核心操作:find找根、union合并
  2. 路径压缩是必加优化,实现简单收益极高
  3. 常见考法:连通块计数、连通性判断、带权并查集(扩展域)等
  4. 解题关键:将题目抽象为「集合合并+连通判断」模型,再套用并查集
http://www.jsqmd.com/news/1341425/

相关文章:

  • 高效开发必备:构建可复用的代码笔记库
  • 智慧断路器原理与优缺点详解|工业选型避坑、断网防护、改造方案科普
  • ST_Link/V2
  • 终极指南:Rosalie‘s Mupen GUI——免费开源的N64模拟器前端
  • 3分钟免费解锁WeMod Pro完整功能:Wand-Enhancer终极指南
  • 如何在ComfyUI中快速搭建LTX-Video视频生成环境?终极指南
  • 重庆办公室除甲醛公司怎么选?本土**启晨环保工装治理全解析 - 重庆在线
  • WanVideo_comfy:一站式解决ComfyUI视频生成模型管理难题的终极工具包
  • deepin 25.2.1 正式版更新!
  • 深度解析 scene-editor:基于 vis-three 的模块化 3D 场景编辑器架构实现
  • 网盘大文件下载提速:解析站与专业下载器组合方案详解
  • 31岁普通后端,3个月转行AI Agent 真实复盘(扎心实话+全套实战)
  • cordova 相关的命令
  • Git克隆HEAD引用异常解析与解决方案
  • 坐席全生命周期管理:优音通信如何让客服团队从“人治”走向“数治”?
  • Nonlinear 3D Face Morphable Model高级应用:人脸重建精度提升与纹理细节优化
  • 天正阀门有限公司主要生产哪些安全阀产品? - 资讯在线
  • 上海虹口区空气净化器租赁公司怎么选?多家对比后优先推荐筠郡(上海)环境科技有限公司 - 专注室内空气检测治理
  • Turbo Intruder进阶:从并发工具到精准攻击逻辑编排器
  • 如何解决中国地图坐标系转换难题:CoordTransform技术深度解析
  • 安卓游戏性能终极优化指南:如何用Magisk_AsoulOpt告别卡顿
  • 2026年河北新绥环保设备有限公司——圆形风管管件专业供应商深度解析 - 卓企推荐
  • 5个关键配置优化技巧:打造企业级OpenAEV攻击模拟平台
  • 为什么scrcpy能成为Android开发者和普通用户的屏幕共享首选?
  • 实时数据大屏与智能报表:优音通信如何让运营数据从“看板”进化为“决策引擎”?
  • 大厂取消前端岗?小白程序员收藏!AI时代前端工程师的转型指南与收藏价值
  • 英雄联盟玩家的智能助手:League Akari全方位提升游戏体验
  • 谷歌助手即将谢幕,Gemini全面接管安卓生态:一场不可逆的语音助手换代
  • 运营不用求技术,AI 帮你写代码
  • AI人工智能培训哪家好?2026年深度解析与机构测评 - IT培训品牌推荐