千家信息网

c++并查集知识点有哪些

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇文章主要介绍"c++并查集知识点有哪些",在日常操作中,相信很多人在c++并查集知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"c++并查集知识点有哪些"
千家信息网最后更新 2026年10月31日c++并查集知识点有哪些

这篇文章主要介绍"c++并查集知识点有哪些",在日常操作中,相信很多人在c++并查集知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"c++并查集知识点有哪些"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

并查集是一种树型的数据结构,用于处理一些不交集的合并及查询问题。

有一个联合- 查找算法定义了两个用于此数据结构的操作:

Find :确定元素属于哪一个子集。它可以被用来确定两个元素是否属于同一子集。 Union:将两个子集合并成同一个集合。

并查集主要运用在合并元素以及查询两个元素是否在同一集合的问题,在信息学竞赛中广泛涉及

初始化:

一开始,每一个元素都是一个集合,打个比方,每个人所在的 "家族" 只有他一个人。我们还需要一个f 数组,里面存的是他的 "父亲" 的编号,初始值为f[1]=1,f[2]=2……f[n]=n,如图

2、find函数:find(a)是用来查找a的"祖先"的,例如,我们要查找 a的祖先,就要去找a 的父亲的父亲……,直到有个人 b,他的父亲就是他自己,那么 b就是 a的祖先代码如下:int find (int x){ if(f[x] == x) return x;//如果x的父亲就是他自己,则x为a的祖先else return find (f[x]);//否则a的祖先 就是a的父亲的祖先}int x=find(a);find函数:find(a)是用来查找a的"祖先"的,例如,我们要查找 a的祖先,就要去找a 的父亲的父亲……,直到有个人 b,他的父亲就是他自己,那么 b就是 a的祖先代码如下:int find (int x){ if(f[x] == x) return x;//如果x的父亲就是他自己,则x为a的祖先else return find (f[x]);//否则a的祖先 就是a的父亲的祖先}int x=find(a);

union函数:

union(a,b)就是合并 a,b这两个人所在的家族,只需要把 a的祖先的父亲 指向 b的祖先

如何合并?我们设u=find(a),v=find(b) , 只要将 u,v其中一个人的父亲编号指向另外一个人就行了,例如f[u]=v

代码如下:

void Union (int a,int b)//因为union是c++的保留字,所以只好大写u{ int u= find(a), v= find(b);//寻找a,b的祖先 f[u]=v;//合并家族}Union (a,b);

在合并的时候还有一个注意点:为什么不能直接把 a的父亲指向 b?因为这样并不能合并完全,a的父亲,a 的父亲的父亲……,都不能合并到b 的家族里(想一想,为什么?),如图

5、查询两个元素是否在同一集合里:查询 a,b是否在同一集合里,就是看他们的祖先是否相等,若相等则在同一集合里,否则就不在代码如下:if( find(a) == find(b) ) cout<<"Y\n"; //如果祖先相等就输出"Y"else cout<<"N\n"; //否则输出"N"查询两个元素是否在同一集合里:查询 a,b是否在同一集合里,就是看他们的祖先是否相等,若相等则在同一集合里,否则就不在代码如下:if( find(a) == find(b) ) cout<<"Y\n"; //如果祖先相等就输出"Y"else cout<<"N\n"; //否则输出"N"

例题:

至此,你应该对并查集有了初步的了解,是时候上例题了

题目描述

如题,现在有一个并查集,你需要完成合并和查询操作。

输入输出格式

输入格式:

第一行包含两个整数N、M,表示共有N个元素和M个操作。

接下来M行,每行包含三个整数Zi、Xi、Yi

当Zi=1时,将Xi与Yi所在的集合合并

当Zi=2时,输出Xi与Yi是否在同一集合内,是的话输出Y;否则话输出N

输出格式:

如上,对于每一个Zi=2的操作,都有一行输出,每行包含一个大写字母,为Y或者N

其实,这道题目就是把上面几个步骤综合在一起,代码如下

并查集的路径压缩

路径压缩,顾名思义,就是将本来要很多步完成的事情压缩成一步

因为我们每次find(a) 都要消耗 O (a的层数) 的时间,如果数据构造成一条链,则每次find 都需要O(n) 的时间,这是我们不希望看到的

所以,我们可以把 f 数组的性质改变一下 f[a] 指向的编号变为a 的祖先

代码该怎么写呢?我们只需要在 find 函数里把

return find (f[x]);

变成

return f[x]=find(f[x]);

就可以了

这样每一次find 都会使路径上的每个f[x] 指向x 的祖先,每一次 find 也就只需要1 步就行了(除非被合并过,那也只需要 2 步),这就是路径压缩的实质

到此,关于"c++并查集知识点有哪些"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

祖先 父亲 就是 输出 两个 元素 代码 查询 知识 c++ 个人 指向 知识点 函数 家族 路径 学习 子集 所在 数据 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 花魁咖啡 深圳恒合互联网络科技有限公司 河南真二互联网科技有限公司 互联网巨头反垄断金融科技 北京互联网科技有限公司 赫美联合互联网科技 互联网科技小额贷款 顺玮阁互联网科技 科技互联网创业计划书 互联网科技素材视频竖屏 互联网巨头投资的硬核科技 开启互联网科技时代小说 青岛中康互联网医疗科技有限公司 顶级互联网科技成果有哪些 搜狐科技互联网 电子商务与互联网科技的关系 万物互联网智能科技 互联网科技创业计划的风险分析 互联网科技快速发展优美句子 小牛互联网科技有限公司地址 互联网科技官网 时间互联网络科技 融贸通互联网科技 互联网养老 桔豆科技 栖莱科技互联网股份有限公司 受益于互联网科技的高速发展 成都铂石互联网科技做什么的 河南住房之家互联网科技 群盈汇互联网科技有限公司 北京市互联网新科技
0