-
Notifications
You must be signed in to change notification settings - Fork 191
/
Copy pathDSU.cpp
61 lines (50 loc) · 1.69 KB
/
DSU.cpp
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/* Disjoint Set Union or Union Find */
/*
https://github.com/the-hyp0cr1t3/CC/blob/master/Beginner%20Topics/%5BS5%5D%20Do%20you%20understand%20the%20graphity%20of%20this%20situation/%5BEP%203%5D%20Spanning%20Trees/%5BPt%201%5D%20Disjoint%20Set%20Union%20%28Union%20Find%29.md
*/
struct DSU {
int n, components;
vector<int> data, rootID, roots;
DSU(int n): n(n), components(n), data(n + 1, -1), rootID(n + 1, -1) {}
int par(int x) {
return data[x] < 0? x : data[x] = par(data[x]);
}
// data[x] = -ve size of component if root, else parent of x (>= 0)
int SZ(int x) {
return -data[par(x)];
}
bool merge(int x, int y) {
x = par(x); y = par(y);
if(x == y) return false;
if(-data[x] < -data[y]) swap(x, y);
data[x] += data[y]; data[y] = x; components--;
return true;
}
// call only once
void getRoots() {
roots.reserve(components);
for(int i = 0; i < n; i++) {
if(data[i] < 0) {
rootID[i] = roots.size();
roots.push_back(i);
}
}
}
};
// ----------------------------------------------
/* v2 */
vector<int> par(n + 1, -1); // par[x] = -ve size of component if root, else parent of x (>= 0)
auto get_par = [&par](int A) {
while(par[A] >= 0) {
if(par[par[A]] >= 0)
par[A] = par[par[A]];
A = par[A];
} return A;
};
auto merge = [&get_par, &par](int A, int B) {
A = get_par(A); B = get_par(B);
if(A == B) return false;
if(-par[A] < -par[B]) swap(A, B);
par[A] += par[B]; par[B] = A;
return true;
};