# Disjoint Set / Union Find Template ###### tags: `algorithm template` `c++` `Union Find` ## C++ ```cpp= class UnionFind { public: UnionFind(int size) : root(size), rank(size) { for (int i = 0; i < size; i++) { root[i] = i; rank[i] = 1; } } int find(int x) { if (x == root[x]) { return x; } return root[x] = find(root[x]); } void unionSet(int x, int y) { int rootX = find(x); int rootY = find(y); if (rootX != rootY) { if (rank[rootX] > rank[rootY]) { root[rootY] = root[rootX]; } else if (rank[rootX] < rank[rootY]) { root[rootX] = root[rootY]; } else { root[rootY] = root[rootX]; rank[rootX] += 1; } } } bool isConnected(int x, int y) { return find(x) == find(y); } private: vector<int> root; vector<int> rank; }; ``` ## Python ```python= class UnionFind: def __init__(self, size): self.root = [i for i in range(size)] self.rank = [1] * size def find(self, x): if x == self.root[x]: return x self.root[x] = self.find(self.root[x]) return self.root[x] def union(self, x, y): rootX = self.find(x) rootY = self.find(y) if rootX != rootY: if self.rank[rootX] > self.rank[rootY]: self.root[rootY] = rootX elif self.rank[rootX] < self.rank[rootY]: self.root[rootX] = rootY else: self.root[rootY] = rootX self.rank[rootX] += 1 def is_connected(self, x, y): return self.find(x) == self.find(y) ``` ## Related Topics ### [LC 1971. Find if Path Exists in Graph](https://hackmd.io/@Alone0506/rJvbF5eSC) ### [LC 721. Accounts Merge](https://leetcode.com/problems/accounts-merge/description/) >### Complexity >n = the number of vertices in the graph. >| | Time Complexity | Space Complexity | >| ----------- | --------------- | ---------------- | >| Constructor | O(n) | O(n) | >| Find | O(α(n)) | O(1) | >| Union | O(α(n)) | O(1) | >| isConnected | O(α(n)) | O(1) | Note: * `n` is the number of vertices in the graph. `α` refers to the `Inverse Ackermann function`. In practice, we assume it's a constant. In other words, O(α(n)) is regarded as O(1) as average. * When using the combination of union by rank and the path compression optimization, the `find` operation will take O(α(n)) time on average. Since `union` and `isConnected` both make calls to `find` and all other operations require constant time, `union` and `isConnected` functions will also take O(α(n)) time on average. ## Note [Leetcode](https://leetcode.com/explore/featured/card/graph/618/disjoint-set/3843/) [代碼隨想錄 - 并查集理论基础](https://gitee.com/programmercarl/leetcode-master/blob/master/problems/%E5%9B%BE%E8%AE%BA%E5%B9%B6%E6%9F%A5%E9%9B%86%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.md)