并查集抽象解释

何谓并查集?

博主的理解就是,就像小时候打架一样。每个人最开始谁都不服谁,直到有一个人把你打服,那么你就会顺从他,当他的小弟。那么渐渐的,把你打服了的那位老大也可能被别人给收拾了。所以,你的老大不停的更换,你的帮派也在不停的扩大更新。但是,在某时,你肯定是不会为你的对立帮派做事情的。但是,现在有个人就问你,你什么时期是跟的哪位老大呀?你就得回答他
(抽象解释。。。)

请看题
在这里插入图片描述
在这里插入图片描述
那么,我们现在举例说明:
假如有3个人a,b,c。
最开始,他们只认自己做老大(谁都不服谁)。但是在某一天,b把a打服了,那么a就跟b混了(a,b为一个集合,这里我们就定义一个数组arr)则arr[a] = b(意思是,a的老大是b)。
这时,a又把c打服了,c臣服于a。则arr[c] = a(c的老大是a),但是,问题来了,现在的c不知道a的老大是b,所以,并查集的关键来了。

int arr[10050];
int Find(int k)//找最终的老大。
{
    if(arr[k] == k)//如果一个人谁也不服谁(自己是自己的老大),那么就是arr[k] == k
        return k;//找到最终的老大,返回
    return arr[k] = Find(arr[k]);//如果他的上面还有老大,那么继续找,同时自己也要更新自己的老大(不然要被老大收拾)。
}

看懂了这里,并查集就差不多了。

这里还有一种不是递归的版本

int arr[10050];
void Find(int x)
{
    while(x != arr[x])
        x = arr[x] = arr[arr[x]];
    return x;
}

其实我觉得这个版本强一点。。嘻嘻嘻
但是实际上递归版本好像是更快一点

终极代码

#include <bits/stdc++.h>
using namespace std;
int arr[10050];
int Find(int k)
{
    if(arr[k] == k)
        return k;
    return arr[k] = Find(arr[k]);
}
int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int n,m;
    cin >> n >> m;
    for(int i = 1;i <= n;i++)//先初始化,自己是自己的老大
        arr[i] = i;
    while(m--)
    {
        int a,b,c;
        cin >> a >> b >> c;
        if(a == 1)
            arr[Find(b)] = Find(c);//c打服了b
        else
            Find(b) == Find(c) ? cout << "Y" << endl : cout << "N" << endl;//如果b,c的老大是同一个人,那么他们互为自己人
    }
}

实际上参考了一下大佬的解释方法~~嘻嘻嘻~
题目链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值