蓝桥杯高频考点——并查集(心血之作)
并查集
- TA Can Do What & why learning
- what
- why
- 原理和结构
- 路径压缩
- 例题讲解
- 题解
- solution 1(50分)
- solution 2(100分)
- 按秩(树高)合并
- 按大小合并
TA Can Do What & why learning
从字面意思上来理解就是,合并(merge)查询 (isCon?)我们需要的集合(set)的一种小算法,其实并没有多难 let’s go!!!
what

并查集主要是解决连通块的问题,例如对于上面的这个由5个村子若干条路构成的简易地图,如果问你1----->5是否是连通的,显然是的,那如果问你3——>5是否连通,显然是false,因为没有任何一条路能从3指向5,这不是很简单吗
why
那我们需要并查集干嘛?
好问题 如果这个图如果需要你自己构造而不是直接给你(动态构造集合关系),你很难或者说没法直接通过给的数据去画出每一个图的时候,并查集就能帮助我们迅速判断是否连通,而往往算法竞赛中的题目都是动态构造的(后面会附上例题),所以学习并查集是很有必要的,不然的话很大概率会超时
传统方式:
假设你有 100 万个村庄,每次新增一条路(动态添加边),如果每次都用 DFS/BFS 重新遍历整个图来判断两个村庄是否连通,时间复杂度会高达 O (N),效率极低。而并查集的find和union操作经过路径压缩和按秩合并优化后,时间复杂度几乎是O(1)
原理和结构
我们需要知道两个概念父节点和祖先,有一点像二叉树章节里的但又不太一样,尤其是对于祖先这个概念,
祖先代表的是:某一个节点不断去寻找他的父节点(递归),直到某一个节点的父节点是他本身(出口)
题外话:我在学习的时候感觉有点像 二叉树章节里面的 求最大深度问题,其实后来我想了一下是很正常的
毕竟树从某种意义上来说是特殊的图
言归正传:我们用一个pre数组来保存每个节点的父亲,我们的数组如下图所示,这里特意需要说的就是 1的父亲是他本身,所以1对应pre数组里头存储的父节点就是1
这句话怎么来理解呢:
其实可以把1看做是上面这个集合(1,2,4,5)的代表元素,也就是根节点,打个比方来说,这个1就是这个集合(家族)里面最年长的,就像家族的 “掌门人” 一样,没有比他更年长的父亲了,所以他的父亲就是他自己。
成员 1 作为这个家族的代表元素(根节点),就像是整个家族的源头,其他成员都是从他这里 “衍生” 出来的,就像一棵大树,成员 1 是树干最顶端的那个起始点,其他成员是从树干上长出来的树枝和树叶。

通过上面的例子大家应该会有一个比较基础的了解,但是在一开始每一个节点都是跟自己是一个连通关系(即指向自身)

就比如在添加1-2这条边的时候,我们就会让2的祖先指向1,在添加2-4这条边的时候,我们就需要注意,打个比方来说
由于2的“钱”已经交给1了,4想要找2要钱是找不到的,只能去找1了,体现在图中就是让4的祖先指向1,
总结来说就是:对于任何非根节点的相连都必须转换成它们各自的根节点相连
那现在我们已经可以用个构建的这个表来判断节点之间是否连通了,就比如1一直找,找到他的祖先是4,这个时间复杂度是O(N)的,但是这只是一次查询的情况如果有n次查询,那么时间复杂度就是O(n方),
那么有没有办法去优化它呢?
其实是有的——路径压缩(没学之前听着恐怖 其实是纸老虎)

路径压缩
我对于路径压缩的理解(可能不完全准确哈):
就是好比你是一个失忆的人,现在知道四个地方,A B C D,你通过不断探索知道了A是经过B C 能走到D的,也就是说你现在知道A到D是连通的,但是每过一段时间 如果一个人问你,你都需要重新走一遍,路径压缩好比就是,你用笔记本记下来了,A到D是通的并且D是终点,(这就引出了路径压缩的核心思想:通过直接记录最终结果(根节点),避免重复计算路径)
同理B,C到D也是通的,我们这里并不关心,A怎么到D,只关心从A能不能到D
压缩完成就是这个情况:

本质:
牺牲空间(存储父指针)换取时间(快速查询)
将树的高度 “压扁”,使得后续的find操作时间复杂度接近 O (1)
这里压扁的是啥?不就是我们寻找的路径path吗
例题讲解

题解
题目说的很直白就是让你用并查集的思路,其中有一个flag Z当它变化的时候,分别对应两种操作:1.合并(merge)2.判断(isCon)
solution 1(50分)
还有50%的测试点,数据非常大,即便关闭同步流,还是超时了吗,还是做不到吗,哈基霜你这家伙…

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 9;
int pre[maxn];//存储父节点int root(int x)
{return pre[x] == x ? x : pre[x] = root(pre[x]);
}
//一切操作都在根上
void Merge(int x, int y)
{pre[root(x)] = root(y);
}bool isCon(int x, int y)
{return root(x) == root(y);
}void init(int N)
{for (int i = 1; i <= N; ++i) pre[i] = i;
}signed main()
{ios::sync_with_stdio(0);int N, M;cin >> N >> M;init(N);while (M--){int Z, X, Y;cin >> Z >> X >> Y;if (Z == 1)Merge(X, Y);else if (Z == 2)printf("%c\n", isCon(X, Y) ? 'Y' : 'N');}return 0;
}
solution 2(100分)
之前代码仅实现路径压缩,未结合按树高或者大小合并,在数据量大 时,树可能因合并顺序不当变得高度很高,导致find操作时间复杂度退化为接近O(n),最终超时。而当前代码通过两种优化,将单次操作的时间复杂度优化至几乎常数级
#include <bits/stdc++.h>
using namespace std;const int maxn = 1e5 + 9;
int pre[maxn];// 存储父节点
int siz[maxn];// 存储集合大小(模拟秩)// 初始化并查集
void init(int N) {for (int i = 1; i <= N; ++i) {pre[i] = i;siz[i] = 1; // 初始时每个集合大小为 1}
}// 查找根节点并路径压缩
int root(int x) {return pre[x] == x ? x : pre[x] = root(pre[x]);
}// 合并两个集合,按集合大小(秩)优化
void Merge(int x, int y) {int rx = root(x);int ry = root(y);if (rx == ry) return; // 已在同一集合,无需合并// 保证将较小集合合并到较大集合if (siz[rx] > siz[ry]) swap(rx, ry); pre[rx] = ry;if (siz[rx] == siz[ry]) siz[ry]++; // 若大小相等,合并后新集合秩+1
}// 判断两个元素是否连通
bool isCon(int x, int y) {return root(x) == root(y);
}signed main() {ios::sync_with_stdio(0);int N, M;cin >> N >> M;init(N);while (M--) {int Z, X, Y;cin >> Z >> X >> Y;if (Z == 1) {Merge(X, Y);} else if (Z == 2) {printf("%c\n", isCon(X, Y) ? 'Y' : 'N');}}return 0;
}
这就引出了下面的优化方法按秩合并和启发式合并
按秩(树高)合并

在这之前啊,我们是不是通过解决 斜树查找退化成链表的问题 学习过平衡二叉树的概念,
这个其实跟这里的按秩合并非常像,解决的问题也很像
比如说上面这张图,如果新增的边是4->3,
那拿3这个节点举例,那他走到根只需要两步,那如果是3->4,那就需要走3步,根节点向右倾斜了
对于一棵树 我们更希望它变成 矮墩墩 而不是长竹竿,所以就需要我们添加边的时候就需要进行比较 矮的指向高的

按大小合并
跟上面跟类似用小的集合指向大的集合 也就是比较少的点会多走一步
void Merge(int x, int y) {int rx = root(x);int ry = root(y);if (rx == ry) return; // 已在同一集合,无需合并// 保证将较小集合合并到较大集合if (siz[rx] > siz[ry]) swap(rx, ry); pre[rx] = ry;if (siz[rx] == siz[ry]) siz[ry]++; // 若大小相等,合并后新集合秩+1
}
相关文章:
蓝桥杯高频考点——并查集(心血之作)
并查集 TA Can Do What & why learningwhatwhy 原理和结构路径压缩例题讲解题解solution 1(50分)solution 2(100分) 按秩(树高)合并按大小合并 TA Can Do What & why learning 从字面意思上来理解就是,合并&a…...
基于概率图模型的蛋白质功能预测
标题:基于概率图模型的蛋白质功能预测 内容:1.摘要 蛋白质功能预测在生物学研究中具有重要意义,能够帮助理解生命过程和疾病机制。本研究的目的是利用概率图模型进行蛋白质功能预测。方法上,收集了大量已知功能的蛋白质数据构建数据集,运用贝…...
Flutter 学习之旅 之 flutter 使用 connectivity_plus 进行网路状态监听(断网/网络恢复事件监听)
Flutter 学习之旅 之 flutter 使用 connectivity_plus 进行网路状态监听(断网/网络恢复事件监听) 目录 Flutter 学习之旅 之 flutter 使用 connectivity_plus 进行网路状态监听(断网/网络恢复事件监听) 一、简单介绍 二、conne…...
Redisson 分布式锁原理
加锁原理 # 如果锁不存在 if (redis.call(exists, KEYS[1]) 0) then# hash结构,锁名称为key,线程唯一标识为itemKey,itemValue为一个计数器。支持相同客户端线程可重入,每次加锁计数器1.redis.call(hincrby, KEYS[1], ARGV[2], 1);# 设置过期时间redis.call(pexpi…...
高频SQL50题 第四天 | 1251. 平均售价、620. 有趣的电影、1075. 项目员工 I、1633. 各赛事的用户注册率
知识点导览:日期大小比较;ifnull(字段,默认值)函数;取余操作;字符串比较like;逆序desc 1251. 平均售价 题目链接:https://leetcode.cn/problems/average-selling-price/description/?envTypest…...
【STM32】SPI通信外设硬件SPI读写W25Q64
SPI通信协议和W25Q64存储器芯片解读笔记: 【STM32】SPI通信协议&W25Q64Flash存储器芯片(学习笔记)-CSDN博客 SPI通信外设 SPI外设简介 STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能&…...
风暴潮、潮汐潮流模拟:ROMS模型如何精准预测海洋现象?
海洋数值模拟的崛起与 ROMS 的关键角色 🌊在海洋科学的浪潮中,海洋数值模拟正以迅猛之势崛起,成为科研与实际应用领域不可或缺的利器。ROMS(Regional Ocean Modeling System)作为其中的佼佼者,凭借其高效、…...
Spring JDBC Template与事务管理:基于XML与注解的实战指南
摘要 本文深入解析Spring JDBC Template与事务管理的核心技术,结合XML配置与注解方式两种主流方案,通过转账案例完整演示数据库操作与事务管理的最佳实践。文章涵盖JDBC Template的核心用法、事务配置语法、常见问题及性能优化建议,帮助开发…...
【Keil5-开发技巧】
Keil5-开发技巧 ■ Keil5利用AStyle插件格式化代码第一步:下载AStyle插件第二步:添加AStyle插件第三步:AStyle插件介绍■ 一键转UTF-8编码■ Keil5利用AStyle插件格式化代码 第一步:下载AStyle插件 AStyle下载 第二步:添加AStyle插件 解压后 astyle-3.6.7-x64 在重命…...
Uniapp:基于 Vue.js 的高效跨平台开发框架
Uniapp 介绍 Uniapp(全称:Universal Application)是一款基于 Vue.js 的跨平台开发框架,由 DCloud 公司开发和维护。它允许开发者使用一套代码同时构建运行在多个平台(如 iOS、Android、Web、小程序、快应用等…...
form 表单内容序列化成一个字符串
html <form id"form1" action"http://localhost:8080/xxx" method"post"> <p >关键字1: <input type "text" name"keyword1" /></p> <p >关键字2: <input t…...
电脑上不了网普通用户排除方法
1:首先通过电脑的运行/CMD/ipconfig /all 命令查看电脑的ip地址是否正常如图: 2:在命令行中运行:ping 127.0.0.1 如图则正常,否则要重新安装网卡驱动 程序。 3:用ping命令,ping一下同网段的电…...
【C#】WinForm自定义控件及窗体
前言 WinForm(Windows Forms)是Microsoft.NET框架中的技术,用于开发Windows桌面应用程序。它提供了一套丰富的控件和组件。通过拖放控件、编写事件处理程序等方式快速构建用户界面。 通过属性窗口定制这些控件的外观和行为。 通过数据绑定&am…...
基于虚拟知识图谱的语义化决策引擎
在数字化转型浪潮中,企业数据资产的价值释放面临两大挑战:海量异构数据的整合困局与业务-技术语义鸿沟。本文解析飞速创软灵燕智能体平台的创新解决方案——通过构建业务语义驱动的虚拟知识图谱系统,实现企业数据的智能认知与决策赋能。 一、…...
七天免登录 为什么不能用seesion,客户端的http请求自动携带cookei的机制(比较重要)涉及HTTP规范
如果是七天免登录,和session肯定没关系,因为session不能持久化,主要是客户端一旦关闭,seesion就失效了/// 所以必须是能持久化的,这就清晰了,要莫在的服务器保存,要摸在客户端设置 cook机制 1. 使用Cookie实现七天免登录 前端(登…...
HarmonyOS:@AnimatableExtend 装饰器自学指南
在最近的项目开发中,我遇到了需要实现复杂动画效果的需求。在探索解决方案的过程中,我发现了 AnimatableExtend 装饰器,它为实现动画效果提供了一种非常灵活且强大的方式。然而,在学习这个装饰器的过程中,我发现相关的…...
主流NoSQL数据库类型及选型分析
在数据库领域,不同类型的数据库针对不同场景设计,以下是四类主流NoSQL数据库的对比分析: 一、核心特性对比 键值数据库(Key-Value) 数据模型:简单键值对存储 特点:毫秒级读写、高并发、无固定…...
kubernetes|云原生|kubeadm-1.25.7集群单master+外部etcd集群+kubeadm-init+cri-docker文件形式快速部署
一、 前言和写作原因 本文做一个kubernetes集群部署记录,实在是部署的东西太多了,害怕忘记,kubernetes集群的部署又细节比较多,因此,在这里做一个尽量详细的记录 三个VMware虚拟机,IP分别为192.168.123.…...
Qt 导入TagLib库
文章目录 0. 前言和环境介绍1. 下载TagLib2. 下载zlib3. 修改.pro文件4. 测试代码 0. 前言和环境介绍 最近在使用Qt写一个播放器,需要解析mp3文件,于是研究了一下如何导入TagLib库 Qt构建套件:Desktop Qt6.8.2 MinGW64-bit Qt Creator安装目录: D:\bit…...
新能源汽车充换站如何实现光储充一体化管理?
长三角某换电站光伏板晒到发烫,却因电网限电被迫切机;北京五环充电站每月多缴6万超容费;深圳物流车充电高峰排队3小时...当95%的充换站深陷“用不起绿电、扛不住扩容、算不清碳账”困局,安科瑞用一组真实数据撕开行业潜规则&#…...
【数据分享】2000—2024年我国省市县三级逐年归一化植被指数(NDVI)数据(年平均值/Shp/Excel格式)
之前我们分享过2000-2024年我国逐年的归一化植被指数(NDVI)栅格数据,该逐年数据是取的当年月归一化植被指数(NDVI)的年平均值。!该数据来源于NASA定期发布的MOD13A3数据集!很多小伙伴拿到数据后…...
【leetcode题解】链表
目录 链表 两数相加 两两交换链表中的节点 重排链表 合并 K 个升序链表(困难) K 个一组翻转链表 链表 1. 常用技巧 画图!!!(直观形象,便于我们理解)引入虚拟“头”节点…...
本地部署Dify 添加Ollama模型DeepSeek
1、准备工作 本地ollama 加载DeepSeek。 安装并登录Dify。 2、添加Ollama模型服务商 在设置-》模型服务上里添加Ollama模型服务商,也叫插件。 3、添加DeepSeek 使用终端命令 ollama list查询deepseek名称,如deepseek-r1:14b。 在Ollama插件冲添加…...
QEMU源码全解析 —— 块设备虚拟化(7)
接前一篇文章:QEMU源码全解析 —— 块设备虚拟化(6) 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM源码解析与应用》 —— 李强,机械工业出版社 特此致谢! QEMU初始化阶段的块设备虚拟化 从模板生成类和类的实例化 上一回在讲解QEMU中类继承…...
图论 | 岛屿数量(深搜,广搜)
岛屿数量 acm模式:99.岛屿数量 核心代码模式: 200. 岛屿数量 思路 遍历grid,如果它是1,则通过bfs/dfs将这个小岛的grid变为0 dfs def dfs(grid,i,j):if i<0 or j<0 or i>len(grid) or j>len(grid[0]):returnif g…...
iOS:GCD信号量、同步、异步的使用方法
信号量的详细用法,可以用此方法进行队列管理 -(void)dispatchSignal{//crate的value表示,最多几个资源可访问dispatch_semaphore_t semaphore dispatch_semaphore_create(3);dispatch_queue_t quene dispatch_get_global_queue(DISPATCH_QUEUE_PRIORI…...
MSP430 Proteus 仿真作品
https://www.dong-blog.fun/post/1998 1 、 电子万年历(采用 DS1302 及 及 TC72 等芯片) 基本要求: 可显示年、月、日、星期、时、分、秒; 有温度显示功能。 发挥部分: 可调节时间和日期; 有农历显示功能 &…...
Windows打开ftp局域网共享
前提是windows已经设置好开机账号密码了,否则教程不适用 第一先打开电脑ftp共享配置 点击保存即可 2.设置要共享到其他电脑的文件路径(如果你要共享整个盘你就设置整个盘,如果是共享盘中某文件就设置某文件,这里是某文件&#x…...
基于HTML的邮件发送状态查询界面设计示例
以下是一个基于HTML的邮件发送状态查询界面设计示例,结合筛选功能、状态展示和重新发送操作,采用Bootstrap框架实现响应式布局: <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"&…...
聊聊langchain4j的MCP
序 本文主要研究一下langchain4j对Model Context Protocol (MCP) 的支持 MCP MCP协议规定了两种传输方式: HTTP:客户端请求一个SSE(Server-Sent Events)通道以从服务器接收事件,然后通过HTTP POST请求发送命令。这…...
