基础数据结构-并查集

该算法的作用
可以把多个点纳入同一个集合,可以在将近O(1)的时间复杂度内找到两个点是否在同一个集合
原理实现
原理 :
比如说有10个点(1-10),开始时把他们都分到10个不同的集合里面,然后开始合并集合,例如合并1,2,3为一个集合
那么,把2, 3的祖宗结点都设为1,p[2] = 1, p[3] = 1,要判断他们是否在一个集合只要判断他们是具有同一个祖宗结点就可以
每一次添加点到集合(把a,添加到b所在的集合里面)里面只要把a的祖宗结点接到b的祖宗结点下面就可以 p[find(a)] = find(b)

小优化(距离压缩) : 每一次找到一个祖宗结点,就把找到的结点直接连接到祖宗结点下面(直接把祖宗结点拉进到了父亲节点的距离,下一次在需要寻找的时候只需要寻找一次就可以)

#include<iostream>
using namespace std;
const int N = 100010;
int p[N];//p[a] = b 表示a的祖宗结点是b
int n, m;
int find(int x)
{
    if(p[x] != x)p[x] = find(p[x]);//递归寻找祖宗结点
    return p[x];//返回祖宗结点
}
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i ++ ) p[i] = i;//初始化
								//代表每一个点的祖宗结点是他本身
    for (int i = 0; i < m; i ++ )
    {
        char ch[2];
        int a, b;
        cin >> ch >> a >> b;
         //cout << ch << ' ' << a << ' ' << b << endl;
        if(ch[0] == 'M')p[find(a)] = find(b);
        else
        {
            if(find(a) == find(b))puts("Yes");
            else puts("No");
        }
    }
    return 0;
}
posted @ 2021-04-12 21:36  梨花满地  阅读(61)  评论(0)    收藏  举报