算法与数据结构----并查集

用法:

主要用于解决一些元素分组的问题。它管理一系列不相交的集合,并支持两种操作:

  • 合并(Union):把两个不相交的集合合并为一个集合。
  • 查询(Find):查询两个元素是否在同一个集合中。

结构和操作实现:

数组实现,b[i]表示第i个元素的父节点,将1-n个元素看作n个不同集合。

初始化状态:

初始状态每个集合只有自己本身。箭头指向这个元素的父节点(父节点为自己本身)。

代码实现初始化:数组下标表示元素,内容表示父节点,开始指向自己;

合并集合:

如1和3两个集合合并,需要找到两集合的祖先(父节点为自己本身的祖先节点)。                              

2和1两个集合合并,1这个集合有1,2,3个元素;同理,合并完后如右下图。

查询集合:

若我们需要找3这元素属于哪个集合,需要对其父节点进行递归找到祖先。

当b[x] == x时,说明x元素为这个集合的祖先,他的子孙都属于x这集合。

当b[x] != x时,说明x元素不是祖先,需要对其父节点b[x]进行递归。

查询集合代码实现:

未压缩路径:
int getroot(int x)
{
	 if(b[x] == x) return x;
	 else return getroot(b[x]);
}
路径压缩:(更快,但破坏原来子和父的关系)
int getroot(int x)
{
	 if(b[x] == x) return x;
	 else return b[x] = getroot(b[x]);
}

合并代码实现:

图一1,3合并,需要找到1,3两个元素所属的集合(集合的祖先)。

合并过程:不在一个集合,将3祖先的父节点指向1的祖先,即b[3] = 3  ==>  b[3] = 1;

void hebin(int x,int y)
{
	 int xp = getroot(x),yp=getroot(y);
	 if(xp != yp) b[xp] = yp;
}

例题:P1551 亲戚icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P1551

思路:亲戚的亲戚也是亲戚,将有亲戚关系的集合都合并,只要两个人在同一个关系集合(祖先相同),两人为亲戚。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值