并查集(union-find set )

适用组别:提高组
难度系数:6

一、集合(set):

集合是由一个或多个确定的元素所构成的整体。集合中的元素有如下三个特征:
1、确定性:一个元素要么属于集合,要么不属于集合。
2、互异性:集合中的元素互不相同。
3、无序性:集合中的元素没有先后顺序。

二、并查集(union-find set):

并查集是一个可以维护集合的数据结构,它能高效支持集合的基本操作。
1、合并两个集合
2、查询两个指定元素是否属于同一个集合。

需要注意,由于计算机存储结构的限制,并查集维护的集合是离散意义下的集合,而不是广义的集合。集合中的元素是有限的。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/****************************************************************
 * C++  并查集
 * date: 2023-6-3
 * author: Alex Li
 * version: 1.2
 * ****************************************************************/
#include <iostream>
using namespace std;


int father[200];
int x,y;
//找x的祖先,通过递归,当到达祖先位置时,返回祖先
int find(int x){
    //不断向上查找祖先
    if(father[x]!=x) return find(father[x]);
    //路径压缩,所有结点指向一个祖先
    //if(father[x]!=x) father[x]=find(father[x]);
    return father[x];
}
//合并祖先
void unionn(int r1,int r2){
    father[r2]=r1;
    }

bool judge(int x,int y){
    x=find(x);
    y=find(y);
    if(x==y)return true;
    else return false;
}

int main(){
    int n,m;
    cin>>n>>m;
    //初始化,每个结点的父结点都试成自己
    for (int i = 1; i <= n; i++)father[i]=i;
    
    
    for (int i = 1; i <= m; i++){
        cin>>x>>y;
        int r1=find(x);
        int r2=find(y);
        if(r1!=r2)unionn(r1,r2);
    }
    cin>>x>>y;
     if(judge(x,y))cout<<"YES";
     else cout<<"NO";
}
 

练习题:见二分图P1525

Scroll to Top