71. 朋友圈(并查集)

在这里插入图片描述

  • 路径压缩是常用的方法,把一颗树的层高扁平化到1层,实现高效率。
    因为在并查集中,我们并不关心一棵树中,谁在谁的下面,我们只关心他们的祖先是谁。也就是根节点,那不如都挂到根节点下面。查询起来就是O(1)的时间复杂度。

  • 而按秩优化,比的是谁的体系更加庞大,节点数量少的挂入节点数量多的门下。这样能极大程度地防止树退化成链表。但是在路径压缩面前,按秩优化所能产生的进一步效益并不高,而且代码实现更复杂。通常只用路径压缩算法足矣。

并查集模板:(路径压缩+按秩优化)

struct UnionSet {
    int fa[MAX_N + 5], size[MAX_N + 5];
    void init(int n) {
        for (int i = 1; i <= n; i++) {
            fa[i] = i;
            size[i] = 1;
        }
    }
    int get(int x) {
        return (fa[x] = (x == fa[x] ? x : get(fa[x])));
    }
    void merge(int a, int b) {
        int aa = get(a), bb = get(b);
        if (size[aa] < size[bb]) swap(aa, bb);
        fa[bb] = aa;
        size[aa] += size[bb];
    }
};

完整代码:

#include<iostream>
using namespace std;
#define MAX_N 10000
struct UnionSet {
    int fa[MAX_N + 5], size[MAX_N + 5];
    void init(int n) {
        for (int i = 1; i <= n; i++) {
            fa[i] = i;
            size[i] = 1;
        }
    }
    int get(int x) {
        return (fa[x] = (x == fa[x] ? x : get(fa[x])));
    }
    void merge(int a, int b) {
        int aa = get(a), bb = get(b);
        if (size[aa] < size[bb]) swap(aa, bb);
        fa[bb] = aa;
        size[aa] += size[bb];
    }
};

UnionSet u;

int main() {
    int n, m;
    cin >> n >> m;
    u.init(n);    
    for (int i = 0; i < m; i++) {
        int a, b, c;
        cin >> a >> b >> c;
        if (a == 1) u.merge(b, c);
        else if (a == 2) {
            cout << (u.get(b) == u.get(c) ? "Yes" : "No") << endl;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值