首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往
您找到你想要的搜索结果了吗?
是的
没有找到

详解(原理+代码实现+应用+优化)

概念 首先我们来了解一下的概念: 是一种树型的数据结构,用于处理一些不相交集合(disjoint sets)的合并及查询问题。常常在使用中以森林来表示。...那我们来写写代码: 假设我们拿到的是一个名字的数组,个数为n 那我们如何存储这些数据跟编号建立映射呢?...实现 那上面我们讲了一下的原理,下面我们就来实现一个,实现完再给大家做总结。 3.1 结构定义 那我们这里就不搞的像上面那样复杂了,因为我们上面的例子直接按编号去搞就行了。...那以后遇到这种题都需要我们手撕一个吗? 其实不需要完整的手撕一个,直接用的思想解题就行了。...用去搞其实就很简单,我们来分析一下: 那这里呢我们还是用一个,当然不一定非得写一个完整的,就可以像上一题第二种方法那样,用到什么接口自己简单实现一下就行了。

2.2K20

是一种用互质的集合对数据进行分类管理的数据结构。 主要实现了两个功能:合并与查询 我们用一个数组fa[i]来表示第i个元素所在集合的根节点。 根节点的父节点指向它自身。...对于题目 DSL_1_A 来说,题目要求实现一个简单的代码如下: #include #include using namespace std; #define...fa[x] = t; return t; } 按秩合并 的按秩合并说白了就是把高度矮的树合并到高度高的树上。...只有使用了路径压缩+按秩合并的,时间复杂度才会低于O(logn) 我们需要使用一个数组Rank[i]来存储第i个节点作为根节点时,它的树的高度。...带权 带权就是在的树的连边上附上权值。 带权的合并,需要把权值也加起来。 其实理解并不困难,就是用一个数组s[i],来存储当前节点到路径压缩后的父节点的权值和。

64640

本篇博客参照了如下博客内容: http://www.cnblogs.com/horizonice/p/3658176.html 是一种树形结构,又叫“不相交集合”,保持了一组不相交的动态集合...---- 初始化 用数组来建立一个,数组下标代表元素,下标对应的值代表父节点,全部初始化为-1,根节点为一个集合的元素个数,数组的长度为的初始连通分量的个数。...要求各集合是不相交的,因此要求x没有在其他集合中出现过。...这里对操作有两种优化:根节点存树高的相反数或者根节点存集合的个数的相反数,这两种方法统称按秩归并。通常选用第二种方法。 归并过程如下图: ?...array[root1]; this->array[root1] = root2; count--; } } } ---- 全部代码如下

35320

​ 在我们需要判断某一些事物之间是否存在一定的关系的时候,我们最好的办法不是使用图而是使用。因为我们关心的是他们之间是否有关系,而不是关心的他们到底存在怎样的关系。 ​...,简单来说就是 n 个集合,我们通过 union 操作来建立两个节点之间的关系。通过 connected 来判断两个节点之间的关系。...那么现在我们知道了 的基本操作就是 union 和 connected 。 逻辑结构: 一开始我们初始化都是初始化 n 个不相关的独立集合。...代码实现的第一个版本: ​ 此时大概了解他们的物理结构和逻辑结构以后我们就可以开始写代码了。...,该用的技巧我们都已经用上了,现在合并操作的时间复杂度是常数,而查找操作的复杂度则是 n+nlogn 应用: ​ 接下来一个的小应用的例子,就是迷宫是否有解,我们就可以使用来找最上面,

1.4K70

简介 是一种高效的数据结构,常用来解决集合的合并和查找问题,常见于图论问题中。 2. 操作 2.1 构建 一般构建为初始时每个节点所属的集合编号即为自己的节点编号。...// 寻找的根节点 int findfather(int x) { return x == father[x] ?...[x] 改变的只是 x 的根节点,而不是整个的根节点,因为本质是依靠其根节点来维护的,所以应该将的根节点的 father 修改为已另一个集合的根节点,从而保证前一个集合被合并到了后一个集合中...stdc++.h> using namespace std; #ifndef _DSF_ #define _DSF_ #define ll long long #define MAXN 505 // ...x : (father[x] = findfather(father[x])); } // 合并并查(将 x 节点所在查集合并到 y 节点所在) void mergefather

46730

把递归和完美的结合在一起的,我们需要先设置三个数组分别 用于 1,找该节点的父节点,2该节点到其祖先节点的距离,3以该节点为祖先节点的点有几个;每次查找然后更新一旦遇到C,就用该节点的祖先节点包含的点数减去这个点到其祖先节点的数量就可以啦...代码 #include #include #include using namespace std; int fa[30500];// 存节点...y的队伍里面,Q x表示查询x然后需要输出x现在的祖先节点是谁,这个节点一共有几个成员,x被移动了几次;另外每组开始的时候需要输出Case x:(这是第几组测试) 解题思路 这个题真的是麻烦,还是带权...代码 #include #include #include using namespace std; int fa[20000],sum[...这个题意识属于带权,构图之类的都很容易但是如何确定关系呢?我怎么确定这两个点冲突了呢?

76220

数组交集差

数组交集差 有任意两个数组,每个数组里面的元素不重复,找出它们的交集、差。 交集、差是什么鬼?...(本文栗子,还会求出属于 B 不属于 A 的集合) 差百度百科 给定两个集合 A,B,把他们所有的元素合并在一起组成的集合,叫做集合 A 与集合 B 的,记作 A∪B,读作 A B。...百度百科 includes 判断是否包含: let one = [1, 2, 3, 4, 5]; let two = [2, 3, 4, 7]; const intersection = (a, b...}); return arr; }; const unionArr = (a, b) => { return Array.from(new Set([...a, ...b])); // 可以理解为合并数组去重...intersection') { // ab数组交集 set = new Set([...a].filter(x => b.has(x))); } else { // ab数组

1.9K30

四十行代码搞定经典的算法

今天是算法与数据结构的第18篇文章,我们一起来看一个经典的数据结构——。 首先我们来解释一下这个数据结构的名称,其实是一个缩写,指的是合并,查指的是查找,自然就是集合。...所以的全称是合并查找集合,那么顾名思义,这是一个用来合并、查找集合的数据结构。...的定义 集合虽然是一个抽象的概念,但是生活当中关于集合的操作其实不少,只是我们身处其中的时候往往习以为常了。 举个例子,比如A和B两个人都是社会精英,两人名下都有一大笔资产。...正是解决了这两类集合相关的问题,即集合的合并与查找。 集合的查找 首先我们来看集合的查找,我们还是看上面那个例子,我们怎么判断两个不同的人是否来自同一个家族呢?...这个算法非常经典,它并不难理解,代码量也很少,效率也高,学习曲线也很平滑,可以说除了使用场景比较窄之外几乎没有缺点。毕竟世上没有完美无缺的算法,这也是算法的魅力所在吧。

69720

入门

请勿转载@HanKin 简介 ,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中...性质 算法不支持分割一个集合。 算法思想 用集合中的某个元素来代表这个集合,该元素称为集合的代表元。 一个集合内的所有元素组织成以代表元为根的树形结构。...判断两个元素是否属于同一合,只需要看他们的代表元是否相同即可。 路径压缩 每次查找的时候,如果路径较长,则修改信息,以便下次查找的时候速度更快。...其实本题只是一个对分离集合()操作的问题。 我们可以给每个人建立一个集合,集合的元素值有他自己,表示最开始时他不知道任何人是它的亲戚。...的“路径压缩”算法:在集合的查找过程中顺便将树的深度降低。采用路径压缩后,每一次查询所用的时间复杂度为增长极为缓慢的ackerman函数的反函数—α(x)。

74420
领券