Nowcoder 106 C.Professional Manager(统计并查集的个数)
Posted Neord
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nowcoder 106 C.Professional Manager(统计并查集的个数)相关的知识,希望对你有一定的参考价值。
题意:
给出四种操作:
1. 合并u,v两棵树
2. 从u所在的集合中删除u
3. 询问u所在集合有多少颗树
4. 询问 u,v是否在同一个集合
分析:
对于删除操作, 只要新开一个点代替原来的点即可。
#include <bits/stdc++.h> using namespace std; const int maxn = 2e5 + 5e4; int f[maxn], cnt[maxn], id[maxn]; //id是负责记录这个点是原来的点还是删除操作后新开的点 void init(){ for(int i = 0; i < maxn; i++){ f[i] = i; cnt[i] = 1; id[i] = i; } } int find(int x){ if(x == f[x]) return x; else { return f[x] = find(f[x]); } } void merge(int u, int v){ int a = find(u); int b = find(v); if(a != b){ f[b] = a; cnt[a] += cnt[b]; cnt[b] = 0; } } int n, q; int main(){ // freopen("1.txt","r", stdin); ios::sync_with_stdio(false); int T; cin >> T; for(int kase = 1; kase <= T; kase++){ cout << "Case #" << kase << ":\n"; init(); cin >> n >> q; int tot = n; for(int i = 0; i < q; i++){ int op, u, v; cin >> op; switch(op){ case 1:{ cin >> u >> v; merge(id[u],id[v]); break; } case 2:{//删除操作,另开一个点代替原来的点 cin >> u; int p = find(id[u]); cnt[p]--; id[u] = ++tot; // f[id[u]] = id[u]; break; } case 3:{ cin >> u; cout << cnt[find(id[u])] << "\n"; break; } case 4:{ cin >> u >> v; if(find(id[u]) == find(id[v])){ cout << "YES\n"; }else cout << "NO\n"; } } } } return 0; }
以上是关于Nowcoder 106 C.Professional Manager(统计并查集的个数)的主要内容,如果未能解决你的问题,请参考以下文章