:D 正在获取一言...

dsu并查集板子

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ref(i,n,x) for(int i=x;i>=n;i--)
#define fo(i, n, x) for (int i = x; i <= n; i++)
struct DSU {
    vector<int> f;  // f[i]表示i的父节点(用于找根节点)
    vector<int> siz;  // siz[i]表示以i为根的集合大小

    DSU() {}
    DSU(int n) { init(n); }  // 构造函数初始化n个节点

    void init(int n) {  // 初始化:每个节点自成一个集合
        f.resize(n+1);  // 节点编号从1开始(预留0索引)
        iota(f.begin(), f.end(), 0);  // f[i] = i(父节点指向自己)
        siz.assign(n, 1);  // 每个集合大小初始为1
    }

    int find(int x) {  // 找x的根节点,带路径压缩(优化查询效率)
        while (x != f[x]) {
            x = f[x] = f[f[x]];  // 路径压缩:让x直接指向祖父节点
        }
        return x;
    }

    bool same(int x, int y) {  // 判断x和y是否在同一个集合(连通)
        return find(x) == find(y);
    }

    bool merge(int x, int y) {  // 合并x和y所在的集合
        x = find(x), y = find(y);
        if (x == y) return false;  // 已在同一集合,无需合并
        siz[x] += siz[y];  // 合并集合大小
        f[y] = x;  // y的根节点指向x的根节点
        return true;
    }

    int size(int x) {  // 返回x所在集合的大小
        return siz[find(x)];
    }
};

void solve(){
    int n,m;
    cin>>n>>m;
    DSU dsu(n);
    dsu.init(n);
    fo(i,m,1){
        int z,x,y;
        cin>>z>>x>>y;
        if(z==1){
            dsu.merge(x,y);
        }
        if(z==2){
            if(dsu.same(x,y))cout<<"Y"<<endl;
            else cout<<"N"<<endl;
        }
    }
    
}
signed main(){
    int t=1;
    //cin>>t;
    while(t--)solve();


    return 0;
}
posted @ 2025-09-02 10:53  呱唧呱唧呱呱呱  阅读(5)  评论(0)    收藏  举报