2 条题解
-
0
按秩合并
#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
#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
信息
- ID
- 867
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 10
- 已通过
- 2
- 上传者