并查集

1 等价关系和等价类


等价关系

       如果集合S中的关系R是自反的,对称的,传递的,则称他为一个等价关系。
——自反:x=x;
——对称:若x=y,则y=x;
——传递:若x=y、y=z,则x=z。要求:x、y、z必须要同一个子集中。

等价类

          如果R是集合S的等价关系。对于任何x∈S,由[x]R={y|y∈S and xRy}给出的集合[x]RS 称为由x∈S生成的一个R的等价类。


2并查集基本操作

划分等价类

</pre><span style="font-size:12px;"></span><pre class="sh-cpp sh-sourceCode" style="font-family:Courier New,Courier,monospace"><span class="sh-symbol"></span><pre class="sh-cpp sh-sourceCode" style="font-family:Courier New,Courier,monospace"><span class="sh-keyword">for</span><span class="sh-symbol">(</span><span class="sh-type">int</span> i <span class="sh-symbol">=</span> <span class="sh-number">0</span> <span class="sh-symbol">;</span> i <span class="sh-symbol"><</span> maxn <span class="sh-symbol">;</span> i <span class="sh-symbol">++)</span>
     fa<span class="sh-symbol">[</span>i<span class="sh-symbol">]</span> <span class="sh-symbol">=</span> i <span class="sh-symbol">;</span>

 

查找

int Find(int x)
{
    if(x == fa[x]) return x ;
    else return fa[x] = Find(fa[x]) ; //路径压缩
}

合并

void Union(int x ,int y)
{
   int fx = Find(id[x]) ;
   int fy = Find(id[y]) ;
   if(fx != fy)
       fa[fx] = fy ;
}

删除

并不是真正地删除某节点。因为并查集是树形结构,所以无法简单的把一个节点从一棵树中删去并维护原来的信息。那这里用到的思想就是还是保持原来的树的结构不变,只是把被删掉的那个点设为虚点,并新建一个点,把原来的点映射到这个新点上,代表以后的操作都是对这个新点进行操作。这样空间开销虽然大,但还是可以解决问题的。

int fa[maxn] , id[maxn] ;
int cnt = n ;
for(int i = 0 ; i < maxn ; i ++)
     fa[i] = i ;
for(int i = 0 ; i < n ; i ++)
     id[i] = i ;
void delete(int x)
{
    id[x] = cnt ++ ;
}


3 并查集应用

(1)并和查有关的集合操作

  并查集可以用于相关的集合操作,如判定一个无向图是否有环,输出一个无向图的连通分量个数,kruscal最小生成树的操作。一些基于集合,有添加其它性质的集合操作。

 题目:TOJ2469 Friends 、TOJ3294 Building Blcok 、TOJ3732 Dragon Balls

(2)种类相关并查集操作

题目中出现的元素分为一些种类,描述中会给出相关的描述信息,判断描述的正确性,即是否有悖于之前对这些元素种类的描述。一般可以增加一个kind属性来表示元素的种类。

题目 :POJ1182 食物链TOJ1706 A Bug’s lifePOJ1733 Parity Game、TOJ3413 How Many Answers Are Wrong

(3)用于优化

并查集更多地应用于 dp 或者贪心中的优化,用来降低复杂度。

题目:TOJ1681 Supermarket

(4)反向进行并查集操作

与并查集不同,给出一个图中原有的一些边,然后给出操作,操作不是向图中添加边,而是在已有的边上,将边删除。对于该种情况,需要把首先读入所有操作,把要求删除的边全部删除,再按照从后往前的顺序处理操作,这样删边操作又重新转化为了添边的操作。

题目:ZOJ3261 Connections in Galaxy War


参考博客: 点击打开链接


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值