洛谷 P3367:[模板] 并查集

【题目来源】
https://www.luogu.com.cn/problem/P3367

【题目描述】
如题,现在有一个并查集,你需要完成合并和查询操作。

【输入格式】
第一行包含两个整数 N,M ,表示共有 N 个元素和 M 个操作。
接下来 M 行,每行包含三个整数 Zi,Xi,Yi。
当 Zi=1 时,将 Xi 与 Yi 所在的集合合并。
当 Zi=2 时,输出 Xi 与 Yi 是否在同一集合内,是的输出 Y ;否则输出 N。​​​​​​​

【输出格式】
对于每一个 Zi=2 的操作,都有一行输出,每行包含一个大写字母,为 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​​​​​​​

【输出样例】
N
Y
N
Y

【数据范围】
对于 15% 的数据,N≤10,M≤20。
对于 35% 的数据,N≤100,M≤10^3。
对于 50% 的数据,1≤N≤10^4,1≤M≤2×10^5。
对于 100% 的数据,1≤N≤2×10^5,1≤M≤10^6,1≤Xi,Yi≤N,Zi∈{1,2}。

【算法分析】
并查集(Union-Find Set)是一种树型数据结构,专用于处理‌不相交集合的合并与查询问题。

【算法代码】

#include <bits/stdc++.h>
using namespace std;

const int maxn=2e5+5;
int pre[maxn];

int find(int x) {
    if(x!=pre[x]) pre[x]=find(pre[x]);
    return pre[x];
}

void merge(int x,int y) {
    int a=find(x);
    int b=find(y);
    if(a!=b) pre[a]=b;
}

int main() {
    int n,m;
    cin>>n>>m;
    for(int i=1; i<=n; i++) pre[i]=i;

    char op;
    int a,b;
    while(m--) {
        cin>>op>>a>>b;
        if(op=='1') merge(a,b);
        else if(find(a)==find(b)) cout<<"Y\n";
        else cout<<"N\n";
    }
    return 0;
}

/*
in:
4 7
2 1 2
1 1 2
2 1 2
1 3 4
2 1 4
1 2 3
2 1 4

out:
N
Y
N
Y
*/



【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/146948171
https://blog.csdn.net/hnjzsyjyj/article/details/146941814

posted @ 2026-09-12 20:20  Triwa  阅读(8)  评论(0)    收藏  举报