FreeTensor
Loading...
Searching...
No Matches
disjoint_set.h
Go to the documentation of this file.
1#ifndef FREE_TENSOR_DISJOINT_SET_H
2#define FREE_TENSOR_DISJOINT_SET_H
3
4#include <type_traits>
5#include <unordered_map>
6#include <vector>
7
8namespace freetensor {
9
10template <typename T> class DisjointSet {
11 struct Node {
12 int parent, rank;
13 T key;
14 };
15
16 std::unordered_map<T, int> idMap_;
17 std::vector<Node> tree_;
18
19 int find(int id) {
20 int root = id;
21 // lookup the root
22 while (tree_[root].parent != root)
23 root = tree_[root].parent;
24 // path compression
25 while (tree_[id].parent != root) {
26 auto &p = tree_[id].parent;
27 id = p;
28 p = root;
29 }
30 return root;
31 }
32
33 void uni(int id0, int id1) {
34 int root0 = find(id0);
35 int root1 = find(id1);
36 if (root0 != root1) {
37 if (tree_[root0].rank < tree_[root1].rank)
38 tree_[root0].parent = root1;
39 else {
40 tree_[root1].parent = root0;
41 if (tree_[root0].rank == tree_[root1].rank)
42 tree_[root1].rank++;
43 }
44 }
45 }
46
47 void add(const T &key) {
48 if (idMap_.contains(key))
49 return;
50 auto prev_size = idMap_.size();
51 idMap_.emplace(key, prev_size);
52 tree_.emplace_back(prev_size, 0, key);
53 }
54
55 public:
56 const T &find(const T &key) {
57 add(key);
58 return tree_[find(idMap_[key])].key;
59 }
60
61 void uni(const T &key0, const T &key1) {
62 add(key0);
63 add(key1);
64 uni(idMap_[key0], idMap_[key1]);
65 }
66};
67
68} // namespace freetensor
69
70#endif
Definition: disjoint_set.h:10
void uni(const T &key0, const T &key1)
Definition: disjoint_set.h:61
const T & find(const T &key)
Definition: disjoint_set.h:56
Definition: allocator.h:9