并查集总结

前言

前几天看到并查集的题目,竟然只会最简单的并查集,看来带权并查集扩展域并查集还要是好好写个笔记复习复习的。

时间复杂度

如果仅仅使用路径压缩的并查集,时间复杂度似乎并不是O(α(n)),详情见这里

扩展域并查集

yxc给出了一种简单易懂的理解扩展域并查集的方式:将并查集中的元素看成一个个条件,两个元素在一个集合中的意义是:如果有一个条件,那么整个集合中的条件都成立。

我来形式化一点:并查集中的每一个元素都是一个语句p,每一个集合S都是一个命题:

p(pS)q(qS,qp)

这样就十分容易理解了。

例如:P2024 [NOI2001] 食物链

注:(x)指并查集中编号为x的元素。

我们定义:

  • (x)表示第x个动物是A
  • (x+n)表示第x个动物是B
  • (x+2n)表示第x个动物是C

这样动物之间的关系就十分清晰了,合并的时候只需满足题意即可。

x和y同类:

  • 如果(x),那么(y);如果(x+n),那么(y+n);如果(x+2n),那么(y+2n)。

x吃y:
由于A吃B,B吃C,C吃A,所以:

  • 如果(x),那么(y+n);如果(x+n),那么(y+2n);如果(x+2n),那么(y)。

判断矛盾同理。

CODE

带权并查集

我们维护一个点到根节点的“距离”(这个“距离”是根据题意抽象得出的,而非真实的距离),以得出该点与集合中其它点的关系。

通常,关系有几种,距离就有几种,具体地,如果有n种关系,就有n种距离,为了方便,一般将距离定义为[0,n1],这样可以使用取模运算方便地得出两点间相对关系。

还是上面的例题,这次使用带权并查集来做。

两只动物之间的关系只有3种,所以我们定义距离:

  • 0:与根节点同类
  • 1:被根节点吃
  • 2:吃根节点

注:x->y意为x吃y

红色的边是根据题意的环形结构推理得出的。

所以,我们会发现当且仅当dx+1dy(mod3)时,x吃y。

同类自然就不用讲,只要dxdy(mod3),x和y就同类。

判断矛盾同理。

维护dx时,只需要暴力维护到根的权值之和即可。这为何是正确的呢?直观地理解,每一个结点都吃更深一层的结点,到了第3层,刚好完成一个循环,也就是第3层的结点和第0层的是同类,
而我们判断关系时又是在同余下处理的,所以自然是正确的。

需要注意的是,如果不做特殊处理,直接累加距离的话,可能会导致距离倍增并溢出。

解决办法有两个:

  1. dx取模;
  2. 在更新dx时,只累加[0,n1]的值(正余数)。

对比

扩展域并查集更加直观、易懂,不易写错,但是也有缺点,就是空间占用过多。

带权并查集关系较为复杂,用到了同余的知识,可能会吃数学的亏(like me),但是空间占用小。


题单

P2294 [HNOI2005]狡猾的商人
(带权并查集)

posted @   Zlc晨鑫  阅读(249)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示