3 条题解

  • 0
    @ 2026-3-24 15:43:38

    解题思路 本题是并查集的经典模板题。 优化 路径压缩:查询根节点时直接将节点指向根

    按集合大小合并:将小集合合并到大集合上,避免树退化成链表,保证合并效率;(随便orz)

    数组维护:用数组记录每个节点的父节点、每个集合的元素数量。

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long 
    int n,m;
    // a:父节点数组  h:集合大小数组
    int a[100100],h[100100];
    // 查找根节点 + 路径压缩
    int find(int x){
        if(a[x]==x)return x;
        return a[x]=find(a[x]); 
    }
    int merge(int x,int y){
        int fx=find(x),fy=find(y);
        if(fx==fy)return 0; // 同一集合,无需合并
        // 按大小合并:小挂到大
        if(h[fx]>h[fy])swap(fx,fy);
        a[fx]=fy;
        h[fy]+=h[fx]; // 更新大小
        return 1;
    }
    signed main(){
        cin>>n>>m;
        // 初始化:每个元素的父节点是自己,集合大小为1
        for(int i=1;i<=n;i++){
            a[i]=i;
            h[i]=1;
        }
        while(m--){
            char op;
            cin>>op;
            if(op=='C'){
                // 合并操作
                int x,y;
                cin>>x>>y;
                if(x==y)continue;
                merge(x,y);
            }
            else if(op=='Q'){
                int type;
                cin>>type;
                if(type==1){
                    // 查询x和y是否连通
                    int x,y;
                    cin>>x>>y;
                    cout<<(find(x)==find(y)?"Yes\n":"No\n");
                }
                else{
                    // 查询x所在集合的大小
                    int x;
                    cin>>x;
                    cout<<h[find(x)]<<'\n';
                }
            }
        }
    }
    

    信息

    ID
    52
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    57
    已通过
    26
    上传者