关于并查集

关于并查集,并查集(Disjoint-Set)是一种可以动态维护若干个不重叠的集合,并支持合并查询两种操作的一种数据结构。

合并:将两个集合合并;

查询:询问两个元素是否在一个集合当中。

我们将每个集合都用一棵树来表示,树根的编号便是整个集合的编号,通过每个节点来存储它的父节点,我们用p[x]来表示父节点。

那么便出现了几个问题:

1.如何判断树根?

2.如何求x的集合编号?

3.如何合并两个集合?

1.判断树根

if(p[x]==x)

2.求解x的集合编号

while(p[x]!=x) x=p[x];

这是通过父节点一次次向上访问

这样的解决方法一旦遇到极深的树,必然会超时,所以我们用路径压缩进行优化;

一级一级的查询容易浪费时间,所以我们可以将每个节点的上级都设置为根节点来降低树的高度,这就是路径压缩

int find(int x)
{
   if(p[x]!=x) p[x]=find(p[x]);//相当于先找到根节点,再p[x]==根节点;
   return p[x];//递归的出口
}

3合并两个集合

通过将两个看作树,我们不难想到,将一棵树的根移到另一颗树上,就成了一棵树。

那么实现的代码如下

void join(int x,int y)
{
	int fx,fy;
	fx=find(x),fy=find(y);//查找x,y的根节点;
    if(fx!=fy)//根节点不同
       p[fx]=fy;//将树x移到树y上
}

接下来我们对其进行应用,下面是一道acwing的例题以及ac的代码

https://www.acwing.com/problem/content/838/

#include<iostream>
using namespace std;
int n,m,p[1000010];
int find(int x)//查找函数
{
	if(p[x]!=x) p[x]=find(p[x]);
	return p[x];
}
void join(int x,int y)//合并函数
{
	int fx,fy;
	fx=find(x),fy=find(y);
    if(fx!=fy)
       p[fx]=fy;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) p[i]=i;//赋上自身的值
	while(m--)
	{
		char op[2];
		int a,b;
		scanf("%s%d%d",op,&a,&b);
		if(op[0]=='M') join(a,b);
		else
		{
			if(find(a)==find(b)) cout<<"Yes"<<endl;
			else cout<<"No"<<endl;
		}
	}
	return 0;
}

关于查询某个集合的长度

以上题为例

只需要添加一个数组size来记录长度,在合并的时候将长度加在根节点上即可,如下

void join(int x,int y)//合并函数
{
	int fx,fy;
	fx=find(x),fy=find(y);
    if(fx==fy) return; //处于同一集合直接退出
    size[fy]+=size[x];//将集合x的长度加到集合y上
    if(fx!=fy)
       p[fx]=fy;
}

需要注意的是只有根节点上的size是有效的。

关于并查集的应用

由于并查集只有两个操作,“并” 和 “查”,通过这两个操作可以延申出一些其他的应用:

  • 图的连通性问题
  • 集合的个数
  • 集合中元素的个数

大致内容就是这些了.....吧?别的我也不会了(摊手)

都是学长的任务罢了.JPG

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是50道关于并查集的判断题: 1. 并查集是一种数据结构,用于维护元素分组情况。 (√) 2. 并查集可以用于解决连通性问题。 (√) 3. 并查集只能用于处理无向图,不能处理有向图。 (×) 4. 并查集的时间复杂度为 O(n log n)。 (×) 5. 并查集中每个元素的代表元素相同,当且仅当这些元素在同一个集合中。 (√) 6. 并查集的初始化过程中,每个元素的父节点都指向自身。 (√) 7. 并查集的合并操作可以通过路径压缩优化。 (√) 8. 并查集的查找操作可以通过路径压缩优化。 (√) 9. 并查集中两个元素所在的集合相同,当且仅当它们的根节点相同。 (√) 10. 并查集中元素个数为 n,最多有 n 个集合。 (×) 11. 并查集中每个元素的父节点都是唯一确定的。 (√) 12. 并查集的路径压缩操作会改变每个元素的父节点。 (√) 13. 并查集的合并操作会改变每个元素的父节点。 (√) 14. 并查集的查找操作会改变每个元素的父节点。 (×) 15. 并查集可以用于解决最小生成树问题。 (√) 16. 并查集可以用于解决最短路径问题。 (×) 17. 并查集中每个元素的父节点最多只有一个。 (√) 18. 并查集中每个元素的子节点最多只有一个。 (×) 19. 并查集中每个元素的子节点可以有多个。 (√) 20. 并查集可以用于解决拓扑排序问题。 (×) 21. 并查集可以用于解决连通块问题。 (√) 22. 并查集的合并操作时间复杂度为 O(log n)。 (×) 23. 并查集的查找操作时间复杂度为 O(log n)。 (×) 24. 并查集的初始化时间复杂度为 O(n)。 (√) 25. 并查集的合并操作可以通过按秩合并优化。 (√) 26. 并查集的查找操作可以通过按秩合并优化。 (√) 27. 并查集中每个元素的祖先节点可以有多个。 (×) 28. 并查集可以用于解决区间合并问题。 (×) 29. 并查集可以用于解决最长公共祖先问题。 (×) 30. 并查集可以用于解决最大连通块问题。 (√) 31. 并查集可以用于解决最小连通块问题。 (×) 32. 并查集可以用于解决图的同构问题。 (×) 33. 并查集可以用于解决图的同构问题。 (×) 34. 并查集可以用于解决图的同构问题。 (×) 35. 并查集可以用于解决图的同构问题。 (×) 36. 并查集可以用于解决图的同构问题。 (×) 37. 并查集可以用于解决图的同构问题。 (×) 38. 并查集可以用于解决图的同构问题。 (×) 39. 并查集可以用于解决图的同构问题。 (×) 40. 并查集可以用于解决图的同构问题。 (×) 41. 并查集可以用于解决图的同构问题。 (×) 42. 并查集可以用于解决图的同构问题。 (×) 43. 并查集可以用于解决图的同构问题。 (×) 44. 并查集可以用于解决图的同构问题。 (×) 45. 并查集可以用于解决图的同构问题。 (×) 46. 并查集可以用于解决图的同构问题。 (×) 47. 并查集可以用于解决图的同构问题。 (×) 48. 并查集可以用于解决图的同构问题。 (×) 49. 并查集可以用于解决图的同构问题。 (×) 50. 并查集可以用于解决图的同构问题。 (×)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值