并查集学习总结

并查集作用:判断两个元素是否在一个集合内。

方式:通过记录每个元素对应的par[x]值来判断,如果两者相等,则为同组,否则为不同组。

_rank[maxn]的作用:_rank[i]记录的是每一个节点所在的树的高度,查询的时候意义不大,但是当两棵树合并的时候,当树的高度小的树连接到树的高度高的树会让树的整体高度较小,而保证查询优化。

状态压缩:并查集的状态压缩通过如下代码实现:

int find(int x){
    if(par[x]==x)
        return x;
   }else{
        return par[x]=find(par[x]);
    }
}

上面的代码可以让所有的节点都直接连到根节点上,这样无论原本的树高度为多少,在这样一次操作后,树的高度都为2。所以在有状态压缩的情况下,_rank的作用非常小,几乎可以忽略。

模板:

const int maxn=1e5+5;
int par[maxn];

void init(int n){
    for(int i=0;i<n;i++){
        par[x]=i;
    }
}

int find(int x){
    if(par[x]==x){
        return x;
    }else{
        return par[x]=find(par[x]);
    }
}

bool unite(int x,int y){
    x=find(x);
    y=find(y);
    if(x==y)return false;
    else{
        par[x]=y;//此处par[y]=x;也可以
        return true;
    }
}

bool same(int x,int y){
    return find(x)==find(y);
} 

其中unite函数也可以不返回布尔值,之所以在那里写了布尔值,是因为这样可以判断是否成功连接,在MST(最小生成树)的生成过程中使用较为方便。

例题:

1.连通

2.食物链

3.真假话

4.反向连通

5.MST

回来找时间再把例题的具体内容补上...

(未完待续)

原文地址:https://www.cnblogs.com/87hbteo/p/8949750.html

时间: 2024-08-23 18:16:22

并查集学习总结的相关文章

并查集--学习详解

[转] 文章作者:yx_th000 文章来源:Cherish_yimi (http://www.cnblogs.com/cherish_yimi/) 昨天和今天学习了并查集和trie树,并练习了三道入门题目,理解更为深刻,觉得有必要总结一下,这其中的内容定义之类的是取自网络,操作的说明解释及程序的注释部分为个人理解.并查集学习: l         并查集:(union-find sets) 一种简单的用途广泛的集合. 并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很

并查集学习

从HOJ1232来学习并查集 #include<iostream> #include<vector> using namespace std; //封装好的并查集 class UF{//union find private: vector<int> v;//存储各个结点 v[i]=j 表示 第i个结点的代表元是j(所在树的根结点) public: //初始化 UF(int n){//初始化 总共有n个结点 刚开始的时候v[i]=i for(int i=0;i<=n

并查集学习2

(转) 并查集由一个整数型的数组和两个函数构成.数组pre[]记录了每个点的前导点是什么,函数find是查找,join是合并. int pre[1000 ]; int find(int x)                                                                                                         //查找根节点 {      int r=x;     while ( pre[r ] != r )

续并查集学习笔记——Gang团伙题解

一言不合先贴题目 Description 在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1. 我朋友的朋友是我的朋友: 2. 我敌人的敌人是我的朋友: 所有是朋友的人组成一个团伙.告诉你关于这n个人的m条信息,即某两个人是朋友,或者某两个人是敌人,请你编写一个程序,计算出这个城市最多可能有多少个团伙? Input 第1行为n和m,N小于1000,M小于5000: 以下m行,每行为p x y,p的值为0或1,p为0时,表示x和y是朋友,p为1时,表示x和y是敌人. Outpu

并查集 (Union-Find Sets)及其应用

定义 并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.常常在使用中以森林来表示. 集就是让每个元素构成一个单元素的集合,也就是按一定顺序将属于同一组的元素所在的集合合并. 主要操作 初始化 把每个点所在集合初始化为其自身. 通常来说,这个步骤在每次使用该数据结构时只需要执行一次,无论何种实现方式,时间复杂度均为O(N). 查找 查找元素所在的集合,即根节点. 合并 将两个元素所在的集合合并为一个集合. 通常来说,合并之前,应先判断两个元素是否属于

并查集入门(转)

并查集入门 并查集学习: l 并查集:(union-find sets) 一种简单的用途广泛的集合. 并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多,如其求无向图的连通分量个数等.最完美的应用当属:实现Kruskar算法求最小生成树. l 并查集的精髓(即它的三种操作,结合实现代码模板进行理解): 1.Make_Set(x) 把每一个元素初始化为一个集合 初始化后每一个元素的父亲节点是它本身,每一个元素的祖先节点也是它本身(也可以根据情况而变). 2.Find_S

【笔记】并查集

描述:并查集是一种对集合进行合并.查询等一系列操作.时间复杂度为O(a(n)) 比O(logn)还快. 代码: 1 int fa[sz];//集合数组 2 void init()//预处理 3 { 4 for(int i=1;i<=n;i++) 5 { 6 fa[i]=i;//初始时每个点都是一个独立的集合 7 rank[i]=0;//按秩合并 初始时每一个集合形成的树的高度为0: 8 } 9 } 10 int find(int x)//查询操作 返回x所在集合的代表元素 11 { 12 ret

算法学习——动态图连通性(线段树分治+按秩合并并查集)

在考场上遇到了这个的板子题,,,所以来学习了一下线段树分治 + 带撤销的并查集. 题目大意是这样的:有m个时刻,每个时刻有一个加边or撤销一条边的操作,保证操作合法,没有重边自环,每次操作后输出当前图下所有联通块大小的乘积. 首先观察到如果没有撤销操作,那么直接用并查集就可以维护,每次合并的时候乘上要合并的两个并查集大小的逆元,然后乘上合并之后的大小即可. 那么来考虑撤销,观察到如果并查集不带路径压缩,应该是可以处理撤销操作的. 但我们并不能直接做,因为并查集的撤销必须按顺序来,就相当于每次合并

【算法学习笔记】41.并查集 SJTU OJ 1283 Mixture

---恢复内容开始--- Description CC非常喜欢化学,并且特别喜欢把一大堆液体倒在一起. 现在CC有n种液体,其中m对会发生反应,现在她想把这n种液体按某种顺序倒入一个容器内,让她获得最刺激的体验,使危险系数尽量大. 我们可以这样计算危险系数,一开始容器内没有任何液体,危险系数为1.每次液体倒入容器时,若容器内已有一种或多种液体会与这种液体发生反应,则危险系数会乘2,否则危险系数不变. 请你求出把这n种液体倒在一起的最大危险系数. Input Format 第一行为两个数n和m.