2 条题解

  • 0
    @ 2026-1-14 11:13:07

    按秩合并

    #include <bits/stdc++.h>
    using namespace std;
    int n, m;
    vector<int> fa, rk, sz;
    int find(int x){
        if(fa[x] == x) return x;
        fa[x] = find(fa[x]); // 路径压缩
        return fa[x];
    }
    void join(int x, int y){
        int rx = find(x), ry = find(y);
        if(rx == ry) return;
        // 按秩合并:秩小的挂到秩大的
        if(rk[rx] < rk[ry]) swap(rx, ry);
        fa[ry] = rx;
        sz[rx] += sz[ry]; // 维护集合大小
        // 如果两棵树秩相同,合并后根的秩+1
        if(rk[rx] == rk[ry]) rk[rx]++;
    }
    int main(){
        ios::sync_with_stdio(false);cin.tie(nullptr);
        cin >> n >> m;
        fa.assign(n + 1, 0);rk.assign(n + 1, 0);sz.assign(n + 1, 1); // 初始秩为0,每个点初始大小为1
        for(int i = 1; i <= n; i++){
            fa[i] = i;
        }
        for(int i = 0; i < m; i++){
            string op;cin >> op;
            if(op[0] == 'M'){
                int a, b;
                cin >> a >> b;
                join(a, b);
            }else{ // Q
                int a;
                cin >> a;
                int rt = find(a);
                cout << sz[rt] << "\n";
            }
        }
        return 0;
    }
    
    • 0
      @ 2026-1-9 12:34:11
      #include <bits/stdc++.h>
      using namespace std;
      int n,m;
      vector<int> fa,sz;
      int find(int x){
          if(fa[x]==x) return x;
          fa[x]=find(fa[x]); // 路径压缩:把x直接挂到根,后续查找更快
          return fa[x];
      }
      void join(int x,int y){
          int rx=find(x),ry=find(y);
          if(rx==ry) return; // 已在同一集合
          //if(sz[rx]<sz[ry]) swap(rx,ry); // 按大小合并:小树挂大树,控制树高
          fa[ry]=rx; // 合并根
          sz[rx]+=sz[ry]; // 维护集合人数
      }
      int main(){
          ios::sync_with_stdio(false);cin.tie(nullptr);cin>>n>>m;
          fa.assign(n+1,0);
          sz.assign(n+1,1);
          for(int i=1;i<=n;i++){
              fa[i]=i; // 初始化:每个人自成一个家族
          }
          for(int i=0;i<m;i++){
              string op;
              cin>>op;
              if(op[0]=='M'){
                  int a,b;
                  cin>>a>>b;
                  join(a,b); // 合并两个家族
              }else{
                  int a;
                  cin>>a;
                  int rt=find(a); // 找到a所在家族的代表元
                  cout<<sz[rt]<<"\n"; // 输出该家族人数
              }
          }
          return 0;
      }
      
      • 1

      👨‍👩‍👧‍👦 A3《家族人口统计》📌

      信息

      ID
      867
      时间
      1000ms
      内存
      256MiB
      难度
      10
      标签
      递交数
      10
      已通过
      2
      上传者