-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunion-find.cpp
81 lines (62 loc) · 1.55 KB
/
union-find.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <bits/stdc++.h>
using namespace std;
// time: O(n) amortized
// space: O(n)
class UnionFind {
public:
vector<int> parents;
vector<int> group_sizes;
int num_elems;
int num_groups;
UnionFind(int size) {
if (size <= 0) return;
num_elems = size;
num_groups = size;
parents.resize(size);
group_sizes.resize(size);
for(int i = 0; i < size; ++i) {
parents[i] = i;
group_sizes[i] = 1;
}
}
int find(int node) {
int root = node;
while (root != parents[root]) {
root = parents[root];
}
// path compression
while (node != parents[node]) {
int next = parents[node];
parents[node] = root;
node = next;
}
return root;
}
bool isConnected(int node1, int node2) {
return find(node1) == find(node2);
}
int groupSize(int node) {
return group_sizes[find(node)];
}
int size() {
return num_elems;
}
int numComponents() {
return num_groups;
}
void join(int node1, int node2) {
int root1 = find(node1);
int root2 = find(node2);
if (root1 == root2)
return;
if (group_sizes[root1] > group_sizes[root2]) {
group_sizes[root1] += group_sizes[root2];
parents[root2] = root1;
}
else {
group_sizes[root2] += group_sizes[root1];
parents[root1] = root2;
}
num_groups--;
}
};