forked from pcb2gcode/pcb2gcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdisjoint_set.hpp
57 lines (51 loc) · 1.41 KB
/
disjoint_set.hpp
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
#ifndef DISJOINT_SET_HPP
#define DISJOINT_SET_HPP
#include <unordered_map>
template <typename node_t>
class DisjointSet {
public:
const node_t& find(const node_t& node) {
const node_t *current = &node;
if (parent.find(*current) == parent.cend()) {
// New node
parent[node] = node;
rank[node] = 0;
return node;
}
while (parent.at(*current) != *current) {
const auto& p = parent[*current];
const auto& pp = parent[p];
parent[*current] = pp;
current = &p;
}
return *current;
}
void join(const node_t& x, const node_t& y) {
const auto& root_x = find(x);
const auto& root_y = find(y);
if (root_x == root_y) {
return;
}
join_unjoined(root_x, root_y);
}
private:
// It's expected that x and y both have themselves as parents.
void join_unjoined(const node_t& x, const node_t& y) {
if (rank[x] < rank[y]) {
join_unjoined(y, x);
return;
}
parent[y] = x;
if (rank[x] == rank[y]) {
rank[x]++;
}
}
// Stores the parent for each node. If the parent isn't in the map
// then the node is its own parent.
std::unordered_map<node_t, node_t> parent;
// Stores the rank of each node, which is an upper bound on the
// height of the subtree below the node. Nodes that aren't in the
// nap are assumed to have a rank of 0.
std::unordered_map<node_t, size_t> rank;
};
#endif // DISJOINT_SET_HPP