数据结构基础——并查集

定义

并查集是一种树形的数据结构,用于处理不相交集合的查询和合并问题
有两种基本操作,查询(find)和合并(merge)
在这里插入图片描述
这里我们用一个通俗的例子
在这里插入图片描述
在这里插入图片描述
火并过程中4和2碰见了,为了确定是不是友军,4向3询问上级,3向1询问上级,发现1是boss,2向1询问上级,发现1是boss,此时2和4有了相同的boss,2和4是一个帮派的,那么就不会发生冲突
在这里插入图片描述
在这里插入图片描述
帮派1被帮派2打败了,帮派2要合并两个帮派,也就是说1的上级变成了6,此时两个帮派合二为一

find函数

现在我们来讲代码实现
直接实现:维护树上每个结点,若该节点是根节点则父亲视为自己

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

但是这样find一次最坏为O(n)有没有更优化的办法呢
还是以上面的例子为例
在这里插入图片描述
这样就大大减少了树的深度
简单来说,就是将x到根节点路径上所有的点的上级都设置为根节点
代码如下

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

merge函数

void merge(int x, int y)
{
	if (find(x) == find(y))return;
	fa[find(x)] = find(y);
}

让我们再来想想优化的事情
这里给出两种思路
1.根据树的高度优化
如果有两棵树,我们将高度较高的树的根节点作为代表元(boss),能优化使合成树的高度最小,实现优化

void newmerge1(int a, int b)//通过树的高度优化
{
	if (find(a) == find(a)) return;
	if (rank[a] > rank[b]) fa[b] = a;		//如果 a的高度大于 b,则令 b的上级为 a
	else								//否则
	{
		if (rank[a] == rank[b]) rank[b]++;	//如果 x的高度和 y的高度相同,则令 y的高度加1
		fa[a] = b;						//让 x的上级为 y
	}				

2.根据子树的结点数来优化
如果有两棵树,我们将结点少的树并到结点多的树上会使所形成的树的形态更优

void newmerge2(int a, int b)//通过结点个数优化
{
  if (find(a) == find(b))return;
  if (sz[a] > sz[b])swap(a, b);
  fa[a] = b; sz[b] = sz[b] + sz[a];
}

模板题

洛谷P3367在这里插入图片描述
代码:

#include<iostream>
using namespace std;
int n,m;
int f[10010];
int p1,p2,p3;
int find(int x)
{
	if(f[x]==x)return x;
	return f[x]=find(f[x]); 
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		f[i]=i;
	}
	while(m--)
	{
		cin>>p1>>p2>>p3;
		if(p1==1)
		{
			f[find(p2)]=find(p3);
		}
		else if(find(p2)==find(p3))cout<<"Y"<<endl;
		else cout<<"N"<<endl;
	}
	return 0;
}

并查集拓展

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青云遮夜雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值