TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
dsu_union_rank.cpp
Go to the documentation of this file.
1
22#include <cassert>
23#include <cstdint>
24#include <iostream>
25#include <vector>
26
27using std::cout;
28using std::endl;
29using std::vector;
30
35class dsu {
36 private:
37 vector<uint64_t> p;
38 vector<uint64_t> depth;
39 vector<uint64_t> setSize;
40 public:
45 explicit dsu(uint64_t n) {
46 p.assign(n, 0);
48 depth.assign(n, 0);
49 setSize.assign(n, 0);
50 for (uint64_t i = 0; i < n; i++) {
51 p[i] = i;
52 depth[i] = 0;
53 setSize[i] = 1;
54 }
55 }
62 uint64_t findSet(uint64_t i) {
64 while (i != p[i]) {
65 i = p[i];
66 }
67 return i;
68 }
76 void unionSet(uint64_t i, uint64_t j) {
78 if (isSame(i, j)) {
79 return;
80 }
82 uint64_t x = findSet(i);
83 uint64_t y = findSet(j);
84
87 if (depth[x] > depth[y]) {
88 std::swap(x, y);
89 }
91 p[x] = y;
92
94 if (depth[x] == depth[y]) {
95 depth[y]++;
96 }
98 setSize[y] += setSize[x];
99 }
108 bool isSame(uint64_t i, uint64_t j) {
109 if (findSet(i) == findSet(j)) {
110 return true;
111 }
112 return false;
113 }
120 vector<uint64_t> getParents(uint64_t i) {
121 vector<uint64_t> ans;
122 while (p[i] != i) {
123 ans.push_back(i);
124 i = p[i];
125 }
126 ans.push_back(i);
127 return ans;
128 }
129};
134static void test1() {
135 /* checks the parents in the resultant structures */
136 uint64_t n = 10;
137 dsu d(n + 1);
138 d.unionSet(2, 1);
139 d.unionSet(1, 4);
140 d.unionSet(8, 1);
141 d.unionSet(3, 5);
142 d.unionSet(5, 6);
143 d.unionSet(5, 7);
144 d.unionSet(9, 10);
145 d.unionSet(2, 10);
146 // keeping track of the changes using parent pointers
147 vector<uint64_t> ans = {7, 5};
148 for (uint64_t i = 0; i < ans.size(); i++) {
149 assert(d.getParents(7).at(i) ==
150 ans[i]); // makes sure algorithm works fine
151 }
152 cout << "1st test passed!" << endl;
153}
158static void test2() {
159 // checks the parents in the resultant structures
160 uint64_t n = 10;
161 dsu d(n + 1);
162 d.unionSet(2, 1);
163 d.unionSet(1, 4);
164 d.unionSet(8, 1);
165 d.unionSet(3, 5);
166 d.unionSet(5, 6);
167 d.unionSet(5, 7);
168 d.unionSet(9, 10);
169 d.unionSet(2, 10);
170
172 vector<uint64_t> ans = {2, 1, 10};
173 for (uint64_t i = 0; i < ans.size(); i++) {
174 assert(d.getParents(2).at(i) ==
175 ans[i]);
176 }
177 cout << "2nd test passed!" << endl;
178}
183int main() {
184 test1(); // run 1st test case
185 test2(); // run 2nd test case
186
187 return 0;
188}
Disjoint sets union data structure, class based representation.
dsu(uint64_t n)
constructor for initialising all data members
uint64_t findSet(uint64_t i)
Method to find the representative of the set to which i belongs to, T(n) = O(logN)
vector< uint64_t > p
keeps track of the parent of ith element
vector< uint64_t > depth
tracks the depth(rank) of i in the tree
bool isSame(uint64_t i, uint64_t j)
A utility function which check whether i and j belongs to same set or not.
void unionSet(uint64_t i, uint64_t j)
Method that combines two disjoint sets to which i and j belongs to and make a single set having a com...
vector< uint64_t > getParents(uint64_t i)
Method to print all the parents of i, or the path from i to representative.
vector< uint64_t > setSize
size of each chunk(set)
static void test2()
Self-implementations, 2nd test.
int main()
Main function.
static void test1()
Self-implementations, 1st test.
#define endl