/** * @file * @brief [DSU (Disjoint sets)](https://en.wikipedia.org/wiki/Disjoint-set-data_structure) * @details * dsu : It is a very powerful data structure which keeps track of different * clusters(sets) of elements, these sets are disjoint(doesnot have a common element). * Disjoint sets uses cases : for finding connected components in a graph, * used in Kruskal's algorithm for finding Minimum Spanning tree. * Operations that can be performed: * 1) UnionSet(i,j): add(element i and j to the set) * 2) findSet(i): returns the representative of the set to which i belogngs to. * 3) getParents(i): prints the parent of i and so on and so forth. * Below is the class-based approach which uses the heuristic of union-ranks. * Using union-rank in findSet(i),we are able to get to the representative of i * in slightly delayed O(logN) time but it allows us to keep tracks of the parent of i. * @author [AayushVyasKIIT](https://github.com/AayushVyasKIIT) * @see dsu_path_compression.cpp */ #include /// for IO operations #include /// for std::vector #include /// for assert using std::cout; using std::endl; using std::vector; /** * @brief Disjoint sets union data structure, class based representation. * @param n number of elements */ class dsu{ private: vector p; /// depth; /// setSize;///depth[y]){ std::swap(x,y); } ///making the shallower tree, root parent of the deeper root p[x] = y; ///if same depth, then increase one's depth if(depth[x] == depth[y]){ depth[y]++; } ///total size of the resultant set setSize[y]+=setSize[x]; } /** * @brief A utility function which check whether i and j belongs to same set or not * @param i element of some set * @param j element of some set * @returns `true` if element i and j are in same set * @returns `false` if element i and j are not in same set */ bool isSame(uint64_t i,uint64_t j){ if(findSet(i) == findSet(j)){ return true; } return false; } /** * @brief Method to print all the parents of i, or the path from i to representative. * @param i element of some set * @returns void */ vector getParents(uint64_t i){ vector ans; while(p[i]!=i){ ans.push_back(i); i = p[i]; } ans.push_back(i); return ans; } }; /** * @brief Self-implementations, 1st test * @returns void */ static void test1() { /* checks the parents in the resultant structures */ uint64_t n = 10; /// ans = {7,5}; for(uint64_t i=0;i ans = {2,1,10}; for(uint64_t i=0;i