并查集可以表示元素中的属于状态,比较重要。其核心元素是father数组,初始化如下:
1 2 3 4 5
| void init() { for(int i = 0; i < n; i++) { father[i] = i } }
|
另外就是查找元素x的父亲:
1 2 3 4 5 6 7 8 9 10
| int find(int x) { while(x != father[x]){ x = father[x]; } }
int find(int x) { return x == father[x] ? x : find(father[x]); }
|
合并集合:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| void merge(int a, int b) { a = find(a), b = find(b); if(find(a) != find(b)) father[b] = a; }
void merge(int a, int b) { a = find(a), b = find(b); if(rank[a] <= rank[b]) father[a] = b; else father[b] = a; if(rank[a] != rank[b] && a != b) rank[b]++; }
|
Acwing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include <iostream> using namespace std; const int MAXN = 100010; char mode; int a, b, n, t;
int father[MAXN], rk[MAXN];
void init() { for(int i = 0; i < n; i++) father[i] = i, rk[i] = 1; }
int find(int x) { return x == father[x] ? x : find(father[x]); }
void merge(int a, int b) { int fathera = find(a), fatherb = find(b); if (rk[fathera] <= rk[fatherb]) father[fathera] = fatherb; else father[fatherb] = fathera; if (rk[fathera] == rk[fatherb] && fathera != fatherb) rk[fatherb] ++; }
int main() { cin >> n >> t; init(); while(t--) { cin >> mode >> a >> b; if(mode == 'M') { merge(a, b); } else { if(find(a) == find(b)) cout <<"Yes\n"; else cout << "No\n"; } } }
|