带权并查集理解
前言:这几天做了几个带权并查集的问题,看了网上的大量博客,也有自己的一些理解,特地总结一下。
文章目录
回顾
理清理论的发展历史有助于了解理论,因此我们先回顾一下普通的并查集。戳这里.和这里,感谢博主带我入门
- 这里有几个值得注意的地方(也是个人做题中踩过的坑)。
- 在包含路径压缩算法的, 调用
find_father(x)
后,x
所在集合不一定
全压缩成了两层,只有x
到root
的路被压缩了。如图:
- 在包含路径压缩算法的, 调用
带权并查集题型特点。
- 带权并查集问题一般是让人推理
两个实体
间的关系。- 1、问题给出了
实体间的一系列现有关系
。 - 2、问题给出了
关系的推理方式
。 - 3、可以通过
两个实体和父节点之间
的关系推理两个节点之间的关系。
- 1、问题给出了
- 解题重点
- 1、定义合理的
r[i]
表示节点i
与其所在集合root节点
之间的关系。 - 2、数学表达式刻画路径压缩时节点和新的父节点关系的更新。
- 3、数学表达式刻画集合合并时,两个集合父节点之间关系的确定。
- 1、定义合理的
例题:
Bug’s Life
题目链接
题目大意:给出一系列昆虫间的交配关系,昆虫只有雄和雌,问是否可能存在同性交配的情况。
看看问题背景:
- 1、首先该问题给出了一系列现有关系
(交配关系)
. - 2、问题给出了关系推理方式
同同为同,异异为同,同异为异
。 - 3、我们只需要记录
a
和b
和父节点的关系,就可以直接推出a
和b
的关系。
若0表示同性,1表示异性
a和父节点c关系 | b和父节点c关系 | a和b关系 |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
解题重点:
- 1、定义
r[a]
:为节点a
和该集合父节点的关系。0表示同性
,1表示异性
. - 2、确定路径压缩式关系的更新方式:
- 我们知道,并查集是递归的从上向下更新的,因此在某一时刻,需要更新的节点和root只隔着一层。如图:
- 我们知道,并查集是递归的从上向下更新的,因此在某一时刻,需要更新的节点和root只隔着一层。如图:
所以当节点a所在集合父节点变化时,我们可以根据r[a]
和r[fa]
来更新r[a]
。
更新前的r[a] | r[f[a]] | 更新后的r[a] |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
可以看到,我们可以根据亦或
或者相加模2
来刻画这样的推理逻辑。
亦或
方式刻画: r[a] = r[a] ^ r[fa]
相加模2
方式刻画: r[a] = (r[a] + r[fa]) % 2
.
- 3、确定合并集合时,父节点间关系的更新:
由于压缩路径的方式,合并集合时,一定是这样的情况。即a/b和fa/fb
都是直接的父子关系。
给出了a和b
是异性,我们如何更具r[a], r[b], a和b是异性三个条件
更新fa
和fb
的关系r[fa]
呢.- 很明显,当采用
亦或
刻画关系时, 我们可以更具这个式子更新r[fa] = r[b]^1^r[a]
- 当采用,当采用
相加模2
时,采用这个式子r[fa] = (r[b] + 1 + r[a]) % 2
- 很明显,当采用
食物链
-
看看问题背景。
- 1、给出了一系列现有关系
(谁吃谁,谁是谁的同类)
- 2、给出了关系推理方式,
三个种类形成一个环形食物链
. - 3、以父节点为参照,可以推出两个实体的食物链关系.
- 1、给出了一系列现有关系
若>好表示吃, =表示同类, <小于表示被吃
a和父节点c关系 | b和父节点c关系 | a和b关系 |
---|---|---|
a>c | b>c | b=a |
a>c | b=c | a>b |
a>c | b<c | b>a |
a=c | b>c | b>a |
a=c | b=c | b=c |
a=c | b<c | a>b |
a<c | b>c | a>b |
a<c | b=c | b>a |
a<c | b<c | b=c |
-
解题重点:
- 1、定义
r[a]
: 0表示和父节点同类,1表示吃父节点,2表示被父节点吃。 - 2、确定路径压缩式关系的更新方式:
所以当节点a所在集合父节点变化时,我们可以根据r[a]
和r[fa]
来更新r[a]
。
经过一系列枚举观察我们最终得到更新关系:r[a] = (r[a]+r[fa])%3
- 3、确定合并集合时,父节点间关系的更新:
r[fa]
=(-r[a]+d-1+r[a]+3) %3
。其中d表示题中给出的关系(1表示a,b为同类,2表示a吃b,更具我们的定义,我们需要将其-1).
- 1、定义
ps:网上说可以使用向量思维,思考了很久,个人感觉这只是一个窍门,并没有办法证明出向量法的正确性。严格来说还是的枚举,不过做题时可是先试试向量思维。