并查集总结

【算法】

【实现】

主要有路径压缩和按秩合并两个优化,有论文证明了不使用按秩合并只用路径压缩的时间复杂度平均也是O(N\alpha (N)),但如果只用按秩合并不加路径压缩复杂度就是O(NlogN)了,在可持久化的时候一般使用只启发式合并的并查集

//路径压缩
int find(int x)
{
  if (x != fa[x])  // x 不是自身的父亲,即 x 不是该集合的代表
    fa[x] = find(fa[x]);  // 查找 x 的祖先直到找到代表,于是顺手路径压缩
  return fa[x];
}
//按秩合并
void union(int x, int y)
{
  int xx = find(x), yy = find(y);
  if (xx == yy) return;
  if (size[xx] > size[yy])  // 保证小的合到大的里
    swap(xx, yy);
  fa[xx] = yy;
  size[yy] += size[xx];
}

【题型】

1.调整顺序后运用并查集

      「NOI2015」程序自动分析

        先处理相等的,利用并查集合为一体,然后判断不等条件,如果有条件不等号两边变量在同一整体里,那么就不合法

        注意还需要离散化一下

     「JSOI2008」星球大战

        倒序处理摧毁即可

2.其他巧妙构造

      P1640 [SCOI2010]连续攻击游戏 

        这道题目要我们先转换为图论的问题,将一个装备的两个属性值连起来,如果一个连通块是一棵树那么这个连通块内的最大值就无法取到,如果连通块内有环,那么这个连通块的所有点都能取到

        看了题解的代码实现非常简介,学到了!代码

3.种类(权值)并查集

在同个种类的并查集中合并,和原始的并查集没什么区别,仍然表达他们是朋友这个含义。

考虑在不同种类的并查集中合并的意义,其实就表达 他们是敌人 这个含义了。

按照并查集美妙的 传递性,我们就能具体知道某两个元素到底是 敌人 还是 朋友 了。

     P1892 [BOI2003]团伙 

        这道题目运用了反集的思想,如果a和b是敌人,合并n+b和a,n+a和b,如果c和a是敌人,合并n+c和a,n+a和c,那么b和c就并在一起了,这样就符合了题目敌人的敌人是朋友的规则。注意这里就不能加上按秩合并的优化了,因为要保证最后的祖先是1-n里面的人 代码

     P2024 [NOI2001] 食物链 

        这道题目要建立三个种类A,B,C,利用并查集维护它们之间的捕食关系,思维难度较大,详见这个题解,十分详细,代码       

        

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值