并查集:合并多个元素为一个集合的操作方法

并查集:集合合并与元素查找 博主按:因为教程所示图片使用的是 github 仓库图片,网速过慢的朋友请移步《并查集:集合合并与元素查找》原文地址。更欢迎来我的小站看更多原创内容:godbmw.com,进行“姿势”交流 ♪(∇*) 1. 什么时候需要并查集? 在一些有 N 个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集... 阅读详情

一、对并查集算法的简要概述

并查集是一个森林状结构,主要思想是让所有要合并的点都在同一个集合中,指向同一个根节点,从而实现极低复杂度的数据查找任务。并查集算法是一个比较高效的算法,时间复杂度大概在 O ( α ( n ) ) O(\alpha(n)) O(α(n)) 左右。并查集可以用来实现合并和独立操作的高效处理,从属关系的询问,以及有依赖背包问题的优化解决方案。我们在本文中将会介绍并查集的几种常见处理的问题。

在并查集算法中,我们定义以下的几个状态:设 f a ( i ) fa(i) fa(i) 表示第 i i i 个点的父节点,而且假设该节点是它的真正根节点,即整棵树的根节点,而非它的祖先。注意,在推导的过程中, f a ( i ) fa(i) fa(i) 可能不仅代表一个固定的值,而最后的 f a ( i ) fa(i) fa(i) 才是正确答案, f a ( i ) fa(i) fa(i) 的值在一次次不断地查找中不断优化,最终取得最优根节点的值。

二、并查集的算法框架

在开始前,我们先定义一个函数 getfa(int x) ,表示求出 x x x 号节点的真正根节点,并通过改进不断优化 getfa() 函数的准确程度。令我们的节点数量为 N N N ,关系的数量为 M M M ,并查集结构的森林为 T T T , T ( x ) T(x) T(x) 表示 x x x 所在节点在 T T T 中的对应的树。

在第一部分,我们说过并查集是一个森林状结构。首先,我们的森林是一个 1 ∼ M 1\sim M 1∼M 的由根节点组成的集合,即 T = { i : ∀ 1 ≤ i ≤ N } T=\{i:\forall 1\le i\le N\} T={i:∀1≤i≤N} 。

接下来,我们进行 M M M 次读入,每一次读入都将它的关系更新。具体更新步骤如下:

  1. 我们先选定一个两个节点 u , v u,v u,v ,表示将要合并这两个节点, 假设它们各有 k 1 , k 2 k_1,k_2 k1​,k2​ 个父节点。
k_1 个父节点
k_2 个父节点
u_k_1
u
v_k_2
v
  1. 接下来,我们从点 u u u 和点 v v v 分别开始搜索,找到它们的根节点 u k 1 u_{k_1} uk1​​ 和 v k 2 v_{k_2} vk2​​ 。
  2. 最后,我们指定一个节点为另一个节点的父节点,这里我们假设 u k 1 u_{k_1} uk1​​ 为 v k 2 v_{k_2} vk2​​ 的父节点,则我们的森林将会变成这样:
k_1 个父节点
k_2 个父节点
u_k_1
v_k_2
u
v

这样,我们就合并了两个集合为一个大集合,这个集合的父节点就是 u k 1 u_{k_1} uk1​​ 。换言之,对于 ∀ i ∈ T ( U ) , T ( V ) , f a ( i ) = u k 1 \forall i\in T(U),T(V),fa(i)=u_{k_1} ∀i∈T(U),T(V),fa(i)=uk1​​ 。

三、具体实施方案

为了实现在 O ( α ( n ) ) O(\alpha(n)) O(α(n)) 的时间内计算出 ∀ 1 ≤ i ≤ N , f a ( i ) \forall 1\le i\le N,fa(i) ∀1≤i≤N,fa(i) 的值,我们需要使用以下优化:

  1. 定义 getfa() 函数如下:
int getfa(int x)
{
	if (x == fa[x]) return x;
	return fa[x] = getfa(fa[x]);
}

这个函数的意义值得讨论,因为它是并查集的全部算法中最重要的一部分:“并”和“查”。
首先,这个函数判断是否到达了递归出口,即如果一个节点的父节点是它本身,则我们判定该节点为根父节点,则我们一路返回这个节点的编号,让它下面的所有节点的父节点都更新为该节点。这样,在同一个集合内的节点都有了一个唯一的根节点,使得这个根节点能够代表整个集合。图例如下:
假设我们有一个节点 u u u ,它的父节点分别是 u 1 , u 2 , u 3 , . . . , u k u_1,u_2,u_3,...,u_k u1​,u2​,u3​,...,uk​ ,则算法的过程可以大概表示为:

找到根父节点,返回 u_k
省略 k-1 个节点
u_k
u_2
u

下面的一行代码是用来寻找 f a ( x ) fa(x) fa(x) 的最优节点。因为我们要设置 f a ( x ) fa(x) fa(x) 为它的真正根节点,则我们需要将 f a ( x ) fa(x) fa(x) 指向 T ( x ) T(x) T(x) 的根节点。通过递归,这可以理解为将 f a ( x ) fa(x) fa(x) 设置为 f a ( f a ( x ) ) fa(fa(x)) fa(fa(x)) ,并不断叠加层数,直到 f a ( f a ( … f a ( x ) …   ) ) = x fa(fa(\dots fa(x) \dots))=x fa(fa(…fa(x)…))=x 为止。

找到根父节点,返回 u_k
省略 k-1 个节点
u_k
father: u_k
u_2
father: u_k
u
father: u_k
  1. 初始化的方法:
    如第一部分所述,在 T T T 中, ∀ 1 ≤ i ≤ N , T ( i ) = { i } \forall 1\le i\le N,T(i)=\{i\} ∀1≤i≤N,T(i)={i} ,则我们可以初始化 f a ( i ) = i fa(i)=i fa(i)=i 。这比较容易实现,代码如下:
void init(int n)
{
	for (int i = 1; i <= n; ++i)
	{
		fa[i] = i;
	}
}
  1. 合并的方法:
    具体的算法如第二部分所述。代码如下:
void merge(int u, int v)
{
	int fx = getfa(u), fy = getfa(v);
	if (fx == fy) continue; // 判断两个节点是否属于同一个集合
	fa[fx] = fy;
}

这里,我们用到了一个优化的方法,即判断两个集合是否已经合并。如果已经合并,则不需要进行下一步的合并操作。
4. 独立的方法:
只需从原来的集合中分隔出一部分即可。如下图所示:

切断
u
v

可见设置 f a ( i ) = i fa(i)=i fa(i)=i 即可。代码如下:

void seperate(int i)
{
	fa[i] = i;
}
  1. 总体效果预览
    并查集类的定义:
class UnionFindSet
{
public:
	int fa[100007];
	
	void init(int n)
	{
		for (int i = 1; i <= n; ++i)
		{
			fa[i] = i;
		}
	}
	
	void seperate(int i)
	{
		fa[i] = i;
	}
	
	void merge(int u, int v)
	{
		int fx = getfa(u), fy = getfa(v);
		if (fx == fy) continue; // 判断两个节点是否属于同一个集合
		fa[fx] = fy;
	}

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

三、并查集的变形应用

1. 并查集查找对象是否在同一个集合内
我们可以直接使用并查集的模版算法,通过使用并查集的 “并” 和 “查” 操作,实现多个集合的处理。比如,我们在每个读入中输入得知两个相同集合内的元素 a , b a,b a,b ,则我们可以查找 f a ( a ) fa(a) fa(a) 和 f a ( b ) fa(b) fa(b) ,如果 f a ( a ) = f a ( b ) fa(a)=fa(b) fa(a)=fa(b) ,则说明两个元素在同一个集合里,无需再次合并;如果 f a ( a ) ≠ f a ( b ) fa(a) \neq fa(b) fa(a)=fa(b) ,则令 f a ( f a ( a ) ) = f a ( b ) fa(fa(a))=fa(b) fa(fa(a))=fa(b) 或 f a ( f a ( b ) ) = f a ( a ) fa(fa(b))=fa(a) fa(fa(b))=fa(a) 。查询 i , j i,j i,j 是否在同一个集合时,只需查询 f a ( i ) fa(i) fa(i) 是否等于 f a ( j ) fa(j) fa(j) 即可。
代码如下:

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

int fa[N];

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

int main()
{
	int n;
	cin >> n;

	for (int i = 1; i <= n; ++i)
	{
		fa[i] = i;
	}

	for (int i = 1, a, b; i <= n; ++i)
	{
		cin >> a >> b;
		
		int fx = getfa(a), fy = getfa(b);
		if (fx == fy) continue;
		fa[fx] = fy;
	}
	
	int q;
	cin >> q;
	for (int i = 1, a, b; i <= q; ++i)
	{
		cin >> a >> b;
		
		if (getfa(a) == getfa(b))
		{
			cout << "YES" << endl;
		}
		else
		{
			cout << "NO" << endl;
		}
	}
}

2. 使用并查集进行集合大小的查询
事实上,我们只需要在 1 的基础上,增加一个数组 g g g 记录当前以每个元素为代表的集合大小,初始化 g i = 1 ( ∀ 1 ≤ i ≤ N ) g_i=1(\forall 1\le i\le N) gi​=1(∀1≤i≤N) ,然后当我们合并两个集合(两个元素)的时候,假设这两个元素分别是 a , b a,b a,b ,则我们可以使用以下等式 g b ← g b + g a g_b\leftarrow g_b+g_a gb​←gb​+ga​ ,不断更新 g g g 数组,此处假设 f a ( f a ( a ) ) = f a ( b ) fa(fa(a))=fa(b) fa(fa(a))=fa(b) 。按照上一题的格式打印答案时,取 g f a ( a ) g_{fa(a)} gfa(a)​ 或 g f a ( b ) g_{fa(b)} gfa(b)​ 即可。

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

int fa[N], g[N];

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

int main()
{
	int n;
	cin >> n;

	for (int i = 1; i <= n; ++i)
	{
		fa[i] = i;
		g[i] = 1;
	}

	for (int i = 1, a, b; i <= n; ++i)
	{
		cin >> a >> b;
		
		int fx = getfa(a), fy = getfa(b);
		if (fx == fy) continue;
		fa[fx] = fy;
		g[fy] += g[fx];
	}

	int q;
	cin >> q;
	for (int i = 1, a, b; i <= q; ++i)
	{
		cin >> a >> b;
		
		if (getfa(a) == getfa(b))
		{
			cout << "YES" << " " << g[getfa(a)] << endl;
		}
		else
		{
			cout << "NO" << endl;
		}
	}
}

3. 使用并查集的思想进行有方向的并查集操作

一般来说,并查集只是将不同的元素合并到一个集合,并没有指定一个固定的值作为所有值的父亲。当一个元素拥有多个父亲节点时,且规定关系是单向的,由于并查集并没有指定关系的单向性,并查集很可能错误地将该节点作为根节点,引发错误,如下图。

Error!
Error!
Error!
a
Wrong father determined
b
correct father
c
correct father
d
correct father

我们可以使用 Floyed 传递闭包,从而利用并查集的原理实现判断两个节点之间的连通状态。注意 Floyed 算法是 O ( n 3 ) O(n^3) O(n3) 级别的时间复杂度,所以我们应该在不大于 n ≤ 500 n \le 500 n≤500 的数据规模内使用 Floyed 算法。

以下程序的输入格式:
第一行一个整数 N N N ,表示节点的数量。
第 2 ∼ N + 1 2 \sim N + 1 2∼N+1 行:每行有若干个整数,输入每个节点的儿子,结束时为 0 0 0 。如果该节点没有儿子,则对应的一行只有一个数字 0 0 0。

#include <bits/stdc++.h>

using namespace std;

const int N = 207;

int n, f[N][N], fa[N];

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

int main()
{
	cin >> n;
	
	for (int i = 1; i <= n; ++i)
	{
		fa[i] = i;
	}
	
	for (int i = 1; i <= n; ++i)
	{
		int x = 0;
		while (cin >> x, x != 0)
		{
			f[i][x] = 1;
		}
	}
	
	for (int k = 1; k <= n; ++k)
	{
		for (int i = 1; i <= n; ++i)
		{
			for (int j = 1; j <= n; ++j)
			{
				f[i][j] |= f[i][k] & f[k][j];
			}
		}
	}
	
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			if (f[i][j])
			{
				fa[j] = fa[i];
			}
		}
	}
	
	int ans = 0;
	for (int i = 1; i <= n; ++i)
	{
		if (fa[i] == i)
		{
			ans++;
		}
	}
	cout << ans << endl;
	
	return 0;
}
C++ 实现并查集 个人来自不同的学校,起先互不相识,每个学生都是一个独立的小团体,现给这些学生进行编号:{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};给以下数组用来存储该小集体,数组中的数字代表:该小集体中具有成员的个数。毕业后,学生们要去公司上班,每个地方的学生自发组织成小分队一起上路,于是:西安学生小分队s1={0,6,7,8}沿着数组表示的树形关系往上一直找到树的根,如果根相同表明在同一个集合,否则不在。遍历数组,数组中元素为负数的个数即为集合的个数。担任队长,负责大家的出行。个人,总共两个朋友圈。 阅读详情

相关推荐

理解合并集合(并查集)

合并集合(Union-Find 或 Disjoint Set Union,简称 DSU)是一种树型数据结构,用于处理动态连接性问题。合并操作(Union):将两个不同的集合合并成一个集合。查找操作(Find):确定某个元素属于哪个集合(即查找该元素的根节点)。合并集合广泛应用于网络连接、图算法、社交网络分析等多个领域。

不语的博客 1001

并查集快速合并

对于一组数据,并查集主要支持两个动作:union(p,q) - 将 p 和 q 两个元素连接起来。find(p) - 查询 p 元素在哪个集合中。isConnected(p,q) - 查看 p 和 q 两个元素是否相连接在一起。在上一小节中,我们用数组的形式表示并查集,实际操作过程中查找的时间复杂度为,但连接效率并不高。本小节,我们将用另外一种方式实现并查集。把每一个元素,看做是一个节点并且指向自己的父节点,根节点指向自己。

unber的博客 301

poj1611并查集求元素所在集合的元素总数

并查集应用:求某元素所在集合的元素个数 题目:已知有n个人,m个团队,已知0号选手有病毒,病毒会传染给他所在任一小组中的人。 求最后有病毒的人的个数。 思路1:对相同团队的人进行合并,最后输出与0在同一集合的元素个数。 即是否满足find(0)==find(i)。 思路2:对相同团队的人进行合并,合并过程中对集合元素个数num也和并,最后找到0的祖先的num即可 思路1: #incl

yuanba_xs的博客 667

并查集的查询与合并详解

find()函数,并查集算法中,最为核心的就是find()函数。在这个算法中,路径压缩给我们的算法效率提高了很多, 并查集是一种树形的数据结构。使用树型结构来存储数据。树根的编号即为整个树的标号,且每个节点存储的数据是他的父节点下标。 并查集被很多OIer认为是最简洁而优雅的数据结构之一,主要用于解决一些元素分组的问题。它管理一系列不相交的集合,并支持两种操作:合并(Un这个也是需要理解的。合并、查询是并查集的两个主要操作,我们也应该熟悉理解。我们对并查集的讲解就到这里,希望以上内容对你有所帮助。

weixin_67596609的博客 1735

潜在图神经网络学习笔记(Latent Graph Neural Networks for Human Skeleton-based Action Recognition)

在本文中,我们从一个新的角度来解决这个问题,通过将非结构化的骨架数据映射到潜在空间,如图2所示,这里称为潜在特征空间或嵌入空间,其中一组项嵌入在一个流形中[ 1 ],并且在潜在空间中彼此更相似的项被放置在彼此更接近的位置。潜在空间中的位置可以被认为是由一组潜在变量定义的,这些潜在变量来源于对象的相似性。将骨架数据嵌入到流形中,消除了远近邻居之间的冗余依赖关系,以解决加权问题。得到具有多尺度聚合特征的稀疏图矩阵结构,以更好地理解骨骼关节的直接加权信息。

qq_45631885的博客 489

别再死记硬背公式了!用Multisim仿真软件,5分钟搞懂三极管放大电路的工作原理

本文介绍如何利用Multisim仿真软件快速掌握三极管放大电路的工作原理,避免死记硬背公式。通过动态实验和参数调整,直观理解三极管的工作状态和放大效果,提升学习效率和实践能力。

weixin_30566063的博客 568

并查集(合并与查找)

并查集

weixin_45746505的博客 1509

Holtek BS45F3833芯片深度剖析:如何用高集成MCU重塑超声波雾化市场格局?

本文深度剖析Holtek BS45F3833芯片如何通过高集成MCU技术重塑超声波雾化市场。该芯片集成了PWM直驱、电容检水、触摸控制等核心功能,显著提升雾化精度和效率,同时降低BOM成本和开发难度。文章通过实测数据和实战案例,展示了其在香薰机、车载设备及工业加湿器等场景的创新应用,为开发者提供了一站式解决方案。

weixin_29192211的博客 413

并查集之合并集合

暴力算法: 1,判断两个元素是否在一个集合内: arr[x]=x;if(arr[x]==arr[y])cout并查集优化并查集: 1,合并两个集合; 2,判断两个元素是否在一个集合内。如图所示:假设有四个集合,分别为{1},{2},{3},{4},用树来表示即为四个根节点。我们给每个......

sync_with_U 790

224G PAM-4 通道的 PCB 和封装设计

该行业正在努力实现层厚非常低的 sub-Dk = 3 材料,以及更先进的加工,这将使封装和 PCB 中的透射电镜截止值更高。当回波损耗占主导地位时,我们基本上需要去除沿互连产生阻抗失配的任何元件,就像上面描述的更光滑的铜和更低的 Dk 值一样。第二个影响是传输线阻抗匹配在 56 GHz 范围内的非常高的频率下非常困难的主要原因之一,另一个因素是 Tx 或 Rx 封装/缓冲器中的寄生效应。由于 PCB 和封装中的长度刻度,这是 BGA 上的焊盘、过孔和球等小结构开始在输入阻抗中产生明显偏差的频率范围。

jkh920184196的博客 841

数据中心——Vxlan基本概念1

东西流量指的就是横向流量-------例如:服务器与服务器之间交换流量南北流量指的就是纵向流量-------例如:客户端和服务器之间的流量以下主要是讲解业务平面的网络架构(一般业务平面就需要用到专用的数据中心交换机)

m0_49864110的博客 1万+

数据结构:并查集——合并集合

一共有 n 个数,编号是 1∼n,最开始每个数各自在一个集合中。

lichengyang的博客 421

15 君正IPC库开发总结

在前面的章节中,我们介绍了君正ISP、视频采集、音频采集、音频播放、云台电机、移动侦测算法、人形侦测算法、移动跟踪算法等的封装。那么,应用层如何使用这些封装好的接口呢?根据设计模式中的依赖倒置原则:高层次的模块不应该依赖于低层次的模块,它们都应该依赖于抽象。因此,应用层应当只能感知到我们封装的接口类,而不应当感知到其对应的具体实现类。

hope_wisdom的技术博客 1662

【并查集】并查集详解及两种优化方法(路径压缩与按秩合并)

文章目录一.简介:二.代表元法三.为什么需要并查集四.并查集的实现五.模板六.两种优化及其利弊 一.简介: 并查集是一种树形的数据结构,用于解决不相交(disjoint)集合的合并及查询问题,包含两种操作: ①合并两个集合 ②查询某个元素属于哪个集合 二.代表元法 用一个集合中的某个元素来代表这个集合 比如集合{2,3,5,7,9},不妨用7来代表这个集合,也可以理解为给这个集合编号/命名为7 并查集采用的正是这样的做法,因此它只解决不相交(不重叠)集合的问题,试想有两个集合都有元素7,并都用7来代表集合了

Qiuker_jl的博客 1万+

AEJoy —— 最受欢迎的 5 个 Ae 表达方式

NOTE] 原文作者我意识到表达式可能令人生畏,有些人宁愿复制粘贴有用的代码,而不愿学习这门语言。对此我完全理解。因此,我想与您分享我的。这些是我几乎在每个项目中都会使用的表达式,我认为它们极大地提升了工作流程。

ShaderJoy 的兴趣技术杂货铺 364

仿真模型简单介绍

同时,各种以伯克利的Spice仿真程序的算法为核心的商用Spice电路仿真工具也随之产生,运行在PC和UNIX平台,许多都是基于原始的SPICE2G6版的源代码,这是一个公开发表的版本,它们都在Spice的基础上做了很多实用化的工作,比较常见的Spice仿真软件有HSpice、Pspice、Spectre、Tspice、SmartSpcie、IsSpice等,虽然它们的核心算法雷同,但仿真速度、精度和收敛性却不一样,其中以Synopsys公司的Hspice和Cadence公司的Pspice最为著名。...

小幽余生不加糖 8002

合并集合(并查集)

并查集将两个集合合并询问两个元素是否在一个集合中基本原理:每个集合用一棵树来表示。树的编号就是整个集合的编号。每个节点存储它的父节点,$p[x]$表示 $x$ 的父节点判断树根求x的集合编号while(p[x]!合并两个集合,这两将x的根节点嫁接到y的根节点, px为x的根节点, py为y的根节点,嫁接p[px] = py。

初九·潜龙勿用的博客 1630

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

基础_并查集_合并集合

并查集(保姆级讲解)

Rockivy的博客 1207

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

并查集求各集合的元素个数

// 1389.cpp : 定义控制台应用程序的入口点。 // 并查集,求每个集合中的元素个数 // 在合并时将子树中的结点数目加到根结点 #include "stdafx.h" #include <iostream> #include <cstdio> #define MAX 100000+5 int father[MAX]; //父节点 int people...

weixin_43979782的博客 1742

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

并查集求集合个数和每个集合中的元素个数

思路:维护一个数组,代表以某个结点为根的树的结点数目,初始化为全1。在合并两个集合时,将秩较小的集合的元素数目加到秩较大的集合上。这里需要注意一下,就是Union过程处理两个祖先相同的结点,此时实际上没有真正的合并这两个结点,所以不需要更新集合的元素数目。至于统计集合个数就比较简单了,直接扫描一遍所有的结点,如果某个结点的祖先结点不是它自己,说明该结点是某个集合的祖先元素,统计这种结点个数即可。

u011575841的专栏 1万+

并查集(按秩合并+路径压缩)基础讲解

并查集入门 并查集算法在很多算法中都会简单的涉及,比如最小生成树的kruskal算法等。其主要功能是检查不同元素是否属于同一个连通块。主要运用是在图相关的内容中。 并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。 内容讲解 主要特征 在不同的不相交集合中选出一个代表元素,称为代表元 一般这个代表元代表这个集合。查找一...

weixin_43933323的博客 1万+

【数据结构 | 并查集】维护元素分组信息,支持高效合并集合、查询元素所在集合

并查集(Disjoint Set Union,简称并查集),也叫不相交集合(一系列没有重复元素的集合),是一种用于处理集合的数据结构。并查集主要专注于两个核心操作:合并和查找

翼同学 1537

并查集(如何将一个元素从一个集合移动到另一集合中)

1.题目引入: I hope you know the beautiful Union-Find structure. In this problem, you’re to implement something similar, but not identical. The data structure you need to write is also a collection of disjoint sets, supporting 3 operations: 1 p q Union the se

weixin_52914088的博客 600

图解并查集:从代码实现到原理剖析,搞定集合合并与查询问题

详细介绍并查集的定位及典型应用,手撕 C++ UnionFindSet 类代码,从底层设计到核心操作逐步拆解。

Dai_renwen的博客 1050

acwing 836. 合并集合 (并查集)

并查集功能:近乎 O(1)如果上述两个功能用暴力做法: 将两个集合合并 这时暴力做法就需要将小集合合并到大集合中,操作效率低,这里可以用并查集优化 并查集原理: 每一个集合用一颗树来维护。有以下规定。问题1 :如何判断树跟 : 问题2 :如何求x的集合编号 : , 只要不是树根,一直往上走 问题3 : 如何合并两个集合 : 根节点加一条线即可,p[x] 是x集合编号,p[y] 是y的集合编号。. 并查集还有一个优化: 当集合中的一个点x 从根节点需要往下查找3次,查找第一遍后,可以修改这条

刘小雨的博客 3354
上一篇: 初等数论基础知识详细解析(1)
下一篇: 最小生成树算法的解题思路与 C++ 算法应用
Aobing_peterJr
博客等级 码龄2年 128粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值