并查集(Disjoint Set)

目录

1.定义

2.初始化

3.查找

4.合并

4.1.按秩合并(启发式合并)

5.例题

题目描述

输入格式

输出格式

输入输出样例

说明/提示


1.定义

并查集,也称为不相交集合数据结构,是一种用于管理元素分组以及查找元素所属组的数据结构。

在并查集中,每个集合通常用一棵树来表示,其中树的根节点代表集合的代表元素。通过查找操作可以找到元素所属的集合,而通过合并操作可以将两个集合合并为一个集合。

顾名思义,并查集支持两种操作:

  • 合并(Union):合并两个元素所属集合(合并对应的树)
  • 查询(Find):查询某个元素所属集合(查询对应的树的根节点),这可以用于判断两个元素是否属于同一集合

并查集在经过修改后可以支持单个元素的删除、移动;使用动态开点线段树还可以实现可持久化并查集。

注意:并查集无法以较低复杂度实现集合的分离。

2.初始化

用一个数组dsu[x]来存x的父节点。

例如:

此时dsu[1] = 1,dsu[6]=3等;

初始时,每个元素都位于一个单独的集合,表示为一棵只有根节点的树,方便起见,最开始每个元素的父节点为自己。

void init(int* fa) {
	for (int i = 1; i <= N; i++)fa[i] = i;
}

3.查找

根节点时集合的代表,查找就是找到元素所在集合的根。

1.如果父节点等于自己,则找到了根并返回。
2.如果还没找到根,则继续递归查找。

int find(int x) {
	if (fa[x] == x) return x;
	return find(fa[x]);
}

如果链式很长这种查找会很耗时,我们可以在返回的同时,将fa[x]的值修改为根节点,即将各节点的父节点都修改为根节点,也叫带路径的查找(路径压缩),这样可以加快以后的查找进程。

int find(int x) {
	if (fa[x] == x) return x;
	return fa[x] = find(fa[x]);
}

4.合并

把一个集合的根节点指向另一个集合的根节点。

void unionset(int x, int y) {//将x的根节点指向y的根节点
	fa[find(x)] = find(y);
}

在并查集中,将小集合的根节点指向大集合的根节点是一种优化策略,通常结合了按秩合并的思想。这个优化策略有助于保持并查集的平衡性,避免树过深,从而提高查找和合并操作的效率。以下是这种优化策略的一些优点:

  1. 平衡性: 将小树合并到大树上可以保持并查集的平衡性。通过始终将高度较小的树合并到高度较大的树上,可以避免出现极端情况下树的高度过高,从而降低了查找操作的时间复杂度。

  2. 减小树的高度: 通过将小树合并到大树上,可以减小整个并查集中树的高度。较低的树高度意味着在进行查找操作时需要遍历的节点数量更少,提高了查找操作的效率。

  3. 降低时间复杂度: 通过维护平衡的树结构,查找和合并操作的平均时间复杂度可以更接近于O(1),提高了整体的操作效率,减小树的高度可以减少下一次查询时的递归次数。

  4. 避免退化: 如果不进行优化,当按照树的深度进行合并时,可能会出现树的退化情况,即树的高度过高,导致操作的效率下降。

4.1.按秩合并(启发式合并)

把小集合的根节点指向大集合的根节点。

void unionset(int x, int y) {
	x = find(x);
	y = find(y);
	if (x == y)return;//在同一个集合不用合并
	if (siz[x] > siz[y])swap(x, y);//如果x的大小大于y的大小,交换,让x表示大集合,y表示小集合
	fa[x] = y;//再将x指向y
	siz[y] += siz[x];
}

算法竞赛按秩合并不常用,因为路径压缩足够好了,不用再用空间换时间。

5.例题

洛谷:P3367 【模板】并查集

题目描述

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

输入格式

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

接下来 M 行,每行包含三个整数 Z_{i},X_{i},Y_{i} 。

当 Z_{i} = 1 时,将 X_{i}​ 与 Y_{i} 所在的集合合并。

当 Z_{i} = 2 时,输出 X_{i}Y_{i} 是否在同一集合内,是的输出 Y ;否则输出 N 。

输出格式

对于每一个 Z_{i} = 2 的操作,都有一行输出,每行包含一个大写字母,为 Y 或者 N 。

输入输出样例

输入 #1复制

4 7
2 1 2
1 1 2
2 1 2
1 3 4
2 1 4
1 2 3
2 1 4

输出 #1复制

N
Y
N
Y

说明/提示

对于 30% 的数据,N≤10,M≤20。

对于 70% 的数据,N≤100,M≤10^{3}

对于 100% 的数据,1≤N≤10^{4},1≤M≤2×10^{5},1≤X_{i}​,Y_{i}≤N,Z_{i}∈{1,2}。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 10001;
int fa[N];
int find(int x) {
	if (fa[x] == x) return x;
	return fa[x] = find(fa[x]);
}
void unionset(int x, int y) {
	fa[find(x)] = find(y);
}
void f(int x, int y) {
	if (find(x) == find(y))cout << "Y" << endl;
	else cout << "N" << endl;
}
void solve() {
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++) fa[i] = i;
	int z, x, y;
	while (m--) {
		cin >> z >> x >> y;
		if (z == 1) {
			unionset(x, y);
		}
		else f(x, y);
	}
}
int main() {
	ios::sync_with_stdio;
	cin.tie(0);
	cout.tie(0);
	solve();
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/422410.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

回溯 Leetcode 47 全排列II

全排列II 给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列。 Leetcode 47 学习记录自代码随想录 示例 1&#xff1a; 输入&#xff1a;nums [1,1,2] 输出&#xff1a; [[1,1,2], [1,2,1], [2,1,1]] 示例 2&#xff1a; 输入&#xff1…

pd sink取电协议芯片介绍

前言&#xff1a; 在如今快节奏生活不断蔓延的背景下&#xff0c;人们对各种事情的处理也渐渐地开始要求在保证质量的情况下&#xff0c;不断加快。手机快充就是一个典型的例子&#xff0c;从开始的18W&#xff0c;30W快充&#xff0c;到现在已经有240W的超级快充出现。在这其…

ICLR 2024|ReLU激活函数的反击,稀疏性仍然是提升LLM效率的利器

论文题目&#xff1a; ReLU Strikes Back: Exploiting Activation Sparsity in Large Language Models 论文链接&#xff1a; https://arxiv.org/abs/2310.04564 参数规模超过十亿&#xff08;1B&#xff09;的大型语言模型&#xff08;LLM&#xff09;已经彻底改变了现阶段人工…

tritonserver学习之八:redis_caches实践

tritonserver学习之一&#xff1a;triton使用流程 tritonserver学习之二&#xff1a;tritonserver编译 tritonserver学习之三&#xff1a;tritonserver运行流程 tritonserver学习之四&#xff1a;命令行解析 tritonserver学习之五&#xff1a;backend实现机制 tritonserv…

【解决】虚幻导入FBX模型不是一个整体

问题&#xff1a; 现在有一个汽车的fbx模型&#xff0c;导入虚幻引擎&#xff0c;导入后变成了很多汽车零件模型。 解决&#xff1a; 把“合并网格体”勾选上&#xff0c;解决问题。

SpringBoot整合JdbcTemplate

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringBoot ✨特色专栏: MySQL学习 🥭本文内容:SpringBoot整合JdbcTemplate 📚个人知识库: Leo知识库,欢迎大家访问 目录 …

MySQL 数据库表设计和优化

一、数据结构设计 正确的数据结构设计对数据库的性能是非常重要的。 在设计数据表时&#xff0c;尽量遵循一下几点&#xff1a; 将数据分解为合适的表&#xff0c;每个表都应该有清晰定义的目的&#xff0c;避免将过多的数据存储在单个表中。使用适当的数据类型来存储数据&…

Python实现PPT演示文稿中视频的添加、替换及提取

无论是在教室、会议室还是虚拟会议中&#xff0c;PowerPoint 演示文稿都已成为一种无处不在的工具&#xff0c;用于提供具有影响力的可视化内容。PowerPoint 提供了一系列增强演示的功能&#xff0c;在其中加入视频的功能可以大大提升整体体验。视频可以传达复杂的概念、演示产…

谷歌seo推广推荐哪家好?

要想挑选好的谷歌seo服务&#xff0c;最好懂得区分这公司是技术型公司还是销售型公司&#xff0c;技术型公司自不必说&#xff0c;他们懂行&#xff0c;能根据自己的技术实力挑选合作伙伴&#xff0c;还能单飞提供顶尖的谷歌优化服务&#xff0c;这就好比你有个问题&#xff0c…

基于MUSIC算法的六阵元圆阵DOA估计matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于MUSIC算法的六阵元圆阵DOA估计matlab仿真. 2.测试软件版本以及运行结果展示 MATLAB2022a版本运行 3.核心程序 ........................................…

win10如何添加指纹登陆

1、首先进入设置,进入下一个设置页面 2、在下一个设置页面内,我们直接使用右上角的搜索框,输入“指纹/finger”进行搜索。回车之后进入设置指纹登陆选项 3、设置指纹登陆的前期是设置好你的密码和pin码(先要设定登录密码和pin码),这里pin和密码都可以直接登陆我们的win10,设…

修改docker默认存储位置【高版本的docker】

一、修改docker默认存储位置 1、停服务 systemctl stop docker 2、修改/etc/docker/daemon.json添加新的dcoker路径 如"data-root": "/mnt/hdd1/docker" 3、保存后重启服务&#xff1a;systemctl restart docker 二、其他服务的命令 systemctl disab…

【数据结构】之优先级队列(堆)

文章目录 一、优先级队列的概念二、优先级队列的模拟实现1.堆的存储2.堆的创建3.代码的实现 一、优先级队列的概念 队列是一种先进先出(FIFO)的数据结构&#xff0c;但有些情况下&#xff0c;操作的数据可能带有优先级&#xff0c;一般出队列时&#xff0c;可能需要优先级高的…

Docker部署前后端服务示例

使用Docker部署js前端 1.创建Dockerfile 在项目跟目录下创建Dockerfile文件&#xff1a; # 使用nginx作为基础镜像 FROM nginx:1.19.1# 指定工作空间 WORKDIR /data/web# 将 yarn build 打包后的build文件夹添加到工作空间 ADD build build# 将项目必要文件添加到工作空间&a…

v70.字符串

1.字符数组 这个字符数组最后加入了0&#xff0c;变成了可以计算的字符数组&#xff0c;属于字符串了。 写0 和 写 ‘\0’ 是一样的。因为单引号里面使用了转义字符&#xff0c;他俩都表示的大小都是十进制的0。只不过占用的内存空间不同&#xff0c;一个是4字节&#xff0c…

微服务简介及其相关技术栈

目录 1、简介 2、技术栈 3、单体架构 4、分布式架构 5、微服务 6、总结 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数据结构和算法&#xff0c;初步涉猎Pyth…

Day20-磁盘管理

Day20-磁盘管理 1. cut 切:2. 磁盘历史和内外部物理结构介绍2.1 磁盘发展趋势和实现措施2.2 磁盘知识的体系结构2.3 机械磁盘的外部结构2.4 SSD固态硬盘的外部结构2.5 固态硬盘内部结构2.6 缓存在服务器各硬件上的速度和大小对比另类维度图解&#xff0c;从上到下由高速到低速&…

【rust】12、编译为 linux x86 目标

一、编译为 linux x86 目标 1.1 musl-cross 要实现 Linux 平台可以运行的程序&#xff0c;那么需要使用 musl 来替代 glibc&#xff0c;musl 实现了Linux libc。 musl 在 macOS 上使用 musl-cross, musl-cross 是用来专门编译到 Linux 的工具链&#xff0c; 下面进行安装&…

【盲源分离】快速理解FastICA算法(附MATLAB绘图程序)

今天讲一个在信号分析领域较为常用的一个方法&#xff0c;即盲源分离算法中的FastICA。 我们先从一个经典的问题引入。 一、鸡尾酒舞会问题 想象一下&#xff0c;你身处一个熙熙攘攘的鸡尾酒舞会中。四周回荡着各种声音&#xff1a;笑声、交谈声、玻璃碰撞声&#xff0c;甚至…

Vmware Fusion 13 安装CentOS、Ubuntu、Windows11虚拟机

Vmware Fusion 13 安装CentOS、Ubuntu、Windows11虚拟机 背景&#xff1a;每次安装都要到处找资源&#xff0c;现在一篇文章足以 文章目录 Vmware Fusion 13 安装CentOS、Ubuntu、Windows11虚拟机一、Mac中安装CentOS虚拟机1️⃣&#xff1a;准备镜像2️⃣&#xff1a;创建虚拟…