算法知识整理(acwing并查集)

目前仅将自己学习acwing的课程进行整理

acxing的板子

#include <iostream>
#include <string>
using namespace std;
const int N=100010;
int p[N]; // 保存集合的编号也就是父节点
int s[N]; // 集合大小 一个集合就是一个连通块注意理解p[n]和s[n]的作用即可
int n,m;
int find(int x) // 查找x的祖宗节点 祖宗节点的特性是 x=p[x] --- 1=p[1] 本身
{
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}
int main()
{
    cin >> n >> m;
    for(int i=1;i<=n;i++)
    {
        p[i]=i; // 初始化每个数都属于一个集合 祖宗节点都是本身
        s[i]=1; // 初始化每个连通块起初大小都为1
    }
    while(m--)
    {
        string op;
        int a,b;
        cin >> op;
        if(op=="C")
        {
            cin >> a >> b;
            if(find(a) != find(b))
            {
                s[find(b)]+=s[find(a)]; // 合并两个集合的大小 成为一个连通块
                p[find(a)] = find(b);   // 先合并大小 再合并两个集合 顺序不能相反
            }
        }
        else if(op=="Q1")
        {
            cin >> a >> b;
            if(find(a) == find(b)) cout << "Yes" << endl;
            else cout << "No" << endl;
        }
        else
        {
            cin >> a;
            cout << s[find(a)] << endl;
        }
    }
    return 0;
}

洛谷的模板

#include <iostream>
using namespace std;
const int N = 10010;
int p[N];

// 路径压缩的find函数
int find(int x) {
    if (p[x] != x) {
        p[x] = find(p[x]);
    }//如果没找到一直寻找父节点
    return p[x];
}

int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) p[i] = i;
    while (m--) {
        int op, a, b;
        cin >> op >> a >> b;
        if (op == 2) {
            if (find(a) == find(b)) {
                puts("Y");
            } else {
                puts("N");
            }
        }
        if (op == 1) {
            p[find(a)] = find(b);
        }
    }
    return 0;
}
测试样例
4 7
2 1 2
1 1 2
2 1 2
1 3 4
2 1 4
1 2 3
2 1 4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值