首页 > 其他 > 详细

并查集(UnionFind)

时间:2019-07-22 13:50:07      阅读:93      评论:0      收藏:0      [点我收藏+]

本质

查询两个元素是否属于同一类

比较形象的是亲戚,A是B的爸爸,B是C的爸爸,问A与C是否有关系;

也可以是城市道路,有1,2,3这三个城市,有道路1 - 2,2 - 3,问1城市能否到达3城市;

样例

第一行包含两个整数N、M,表示共有N个元素和M个操作。

接下来M行,每行包含三个整数Zi、Xi、Yi

当Zi=1时,将Xi与Yi所在的集合合并

当Zi=2时,输出Xi与Yi是否在同一集合内,是的话输出Y;否则话输出N;

4 7
2 1 2
1 1 2
2 1 2
1 3 4
2 1 4
1 2 3
2 1 4

朴素代码

#include <bits/stdc++.h>

using namespace std;

const int N = 100001;

int n,m;
int fa[N];

int find(int x){
    return fa[x] == x ? x : find(fa[x]);
}

void uni(int x, int y){
    fa[find(x)] = find(y);
}

int ask(int x, int y){
    return find(x) == find(y);
}
int main(){
    cin >> n >> m;
    for(int i = 1; i <= n; ++i) fa[i] = i; // 最开始只和自己有关系
    for(int i = 1, x, y, z; i <= m; ++i){
        cin >> z >> x >> y;
        if(z == 1) uni(x, y);
        else ask(x, y) == true ? printf("Y\n") : printf("N\n");
    }
    return 0;
}

 优化

  1. 按秩合并
  2. 路径压缩

路径压缩

如果我们只考虑他们祖先,不考虑各个之间的具体关系,就可以在find函数里加个优化

代码

int find(int x){
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}

 

并查集(UnionFind)

原文:https://www.cnblogs.com/Adventurer-H/p/11224896.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!