Related Articles

# Dynamic Disjoint Set Data Structure for large range values

• Difficulty Level : Hard
• Last Updated : 30 Jul, 2021

Prerequisites:

Disjoint Set data structure is used to keeps track of a set of elements partitioned into a number of disjoint (non-overlapping) subsets.

In this article, we will learn about constructing the same Data Structure dynamically. This data structure basically helps in situation where we cannot simply use arrays for creating disjoint sets because of large inputs of order 109.

To illustrate this, consider the following problem. We need to find the total number of connected components in the Graph when the total Number of Vertices can be up to 10^9.

Examples:

```Input : Edges : { { 1, 2 },
{ 2, 3 },
{ 4, 5 } }
Output : 2
Explanation: {1, 2, 3} forms a component and
{4, 5} forms another component.```

The idea to solve this problem is, we will maintain two hash tables (implemented using unordered_maps in C++). One for parent and other for degree. Parent[V] will give the parent of the component which the Vertex V is part of and Degree will give the number of vertices in that component.

Initially, both Parent and Degree will be empty. We will keep inserting vertices to the maps as sequentially.
See the code and the explanation simultaneously for a better understanding. Below are the methods used in the code to solve the above problem:

1. getParent(V): This method will give the parent of the vertex V. Here we recursively find the parent of the vertex V( see code), meanwhile we assign all the vertex in that component to have the same parent.( In disjoint set data structure all the vertex in the same component have the same parent.)
2. Union(): When we add a edge and the two vertexes are of different components we call the Union() method to join both the component. Here the parent of the component formed after joining both the components will be the parent of the component among the two which had more number of vertexes before the union. The degree of the new component is updated accordingly.
3. getTotalComponent(): Vertex in the same component will have the same parent.
We use unordered_set (STL) to count the total number of components. As we have maintained the Data Structure as Dynamic so, there can be any vertex which has not been added to any of the components hence they are different component alone. So the total number of components will be given by,
```Total no of Component =  Total Vertices - Number of Vertices
in parent (Map)  + Number of Component
formed from the Vertexes inserted
in the graph.```

Below is the implementation of above idea:

## C++

 `// Dynamic Disjoint Set Data Structure``// Union-Find` `#include ``using` `namespace` `std;` `int` `N;``int` `Edges;` `// Dynamic Disjoint Set Data Structure``struct` `DynamicDisjointSetDS {` `    ``// We will add the vertex to the edge``    ``// only when it is asked to i.e. maintain``    ``// a dynamic DS.``    ``unordered_map<``int``, ``int``> parent, degree;` `    ``// Total nomber of Vertex in the Graph``    ``int` `N;` `    ``// Constructor``    ``DynamicDisjointSetDS(``int` `n)``    ``{``        ``N = n;``    ``}` `    ``// Get Parent of vertex V``    ``int` `getParent(``int` `vertex)``    ``{` `        ``// If the vertex is already inserted``        ``// in the graph``        ``if` `(parent.find(vertex) != parent.end()) {` `            ``if` `(parent[vertex] != vertex) {``                ``parent[vertex] =``                      ``getParent(parent[vertex]);``                ``return` `parent[vertex];``            ``}``        ``}` `        ``// if the vertex is operated for the first``        ``// time``        ``else` `{` `            ``// insert the vertex and assign its``            ``// parent to itself``            ``parent.insert(make_pair(vertex, vertex));` `            ``// Degree of the vertex``            ``degree.insert(make_pair(vertex, 1));``        ``}` `        ``return` `vertex;``    ``}` `    ``// Union by Rank``    ``void` `Union(``int` `vertexA, ``int` `vertexB)``    ``{``        ``// Parent of Vertex A``        ``int` `x = getParent(vertexA);` `        ``// Parent of Vertex B``        ``int` `y = getParent(vertexB);` `        ``// if both have same parent``        ``// Do Nothing``        ``if` `(x == y)``            ``return``;` `        ``// Merging the component``        ``// Assigning the parent of smaller Component``        ``// as the parent of the bigger Component.``        ``if` `(degree[x] > degree[y]) {``            ``parent[y] = x;``            ``degree[x] = degree[x] + degree[y];``        ``}``        ``else` `{``            ``parent[x] = y;``            ``degree[y] = degree[y] + degree[x];``        ``}``    ``}` `    ``// Count total Component in the Graph``    ``int` `GetTotalComponent()``    ``{``        ``// To count the total Component formed``        ``// from the inserted vertex in the Graph``        ``unordered_set<``int``> total;` `        ``// Iterate through the parent``        ``for` `(``auto` `itr = parent.begin();``            ``itr != parent.end(); itr++) {` `            ``// Add the parent of each Vertex``            ``// to the set``            ``total.insert(getParent(itr->first));``        ``}` `        ``// Total Component = Total Vertexes -``        ``// Number of Vertex in the parent +``        ``// Number of Component formed from``        ``// the Vertexes inserted in the Graph``        ``return` `N - parent.size() + total.size();``    ``}``};` `// Solve``void` `Solve()``{` `    ``// Declaring the Dynamic Disjoint Set DS``    ``DynamicDisjointSetDS dsu(N);` `    ``// Traversing through the Edges``    ``for` `(``int` `i = 0; i < 3; i++) {` `        ``// If the Vertexes in the Edges``        ``// have same parent do nothing``        ``if` `(dsu.getParent(Edges[i]) ==``            ``dsu.getParent(Edges[i])) {``            ``continue``;``        ``}` `        ``// else Do Union of both the Components.``        ``else` `{``            ``dsu.Union(Edges[i], Edges[i]);``        ``}``    ``}` `    ``// Get total Components``    ``cout << dsu.GetTotalComponent();``}` `// Driver Code``int` `main()``{``    ``// Total Number of Vertexes``    ``N = 5;``    ` `    ``/* Edges``    ``* 1 <--> 2``    ``* 2 <--> 3``    ``* 4 <--> 5    */` `    ``Edges = 1;``    ``Edges = 2;``    ``Edges = 2;``    ``Edges = 3;``    ``Edges = 4;``    ``Edges = 3;` `    ``// Solve``    ``Solve();` `    ``return` `0;``}`

## Python3

 `# Dynamic Disjoint Set Data Structure``# Union-Find` `# Dynamic Disjoint Set Data Structure``class` `DynamicDisjointSetDS:` `    ``# Constructor``    ``def` `__init__(``self``, n):``        ` `        ``# Total nomber of Vertex in the Graph``        ``self``.N ``=` `n``        ` `        ``# We will add the vertex to the edge``        ``# only when it is asked to i.e. maintain``        ``# a dynamic DS.``        ``self``.parent ``=` `{}``        ``self``.degree ``=` `{}` `    ``# Get Parent of vertex V``    ``def` `getParent(``self``, vertex):``    ` `        ``# If the vertex is already inserted``        ``# in the graph``        ``if` `vertex ``in` `self``.parent:` `            ``if` `self``.parent[vertex] !``=` `vertex:``                ``self``.parent[vertex] ``=` `\``                    ``self``.getParent(``self``.parent[vertex])``                    ` `                ``return` `self``.parent[vertex]` `        ``# if the vertex is operated``        ``# for the first time``        ``else``:` `            ``# insert the vertex and assign``            ``# its parent to itself``            ``self``.parent[vertex] ``=` `vertex` `            ``# Degree of the vertex``            ``self``.degree[vertex] ``=` `1``        ` `        ``return` `vertex``    ` `    ``# Union by Rank``    ``def` `Union(``self``, vertexA, vertexB):``    ` `        ``# Parent of Vertex A``        ``x ``=` `self``.getParent(vertexA)` `        ``# Parent of Vertex B``        ``y ``=` `self``.getParent(vertexB)` `        ``# if both have same parent``        ``# Do Nothing``        ``if` `x ``=``=` `y:``            ``return` `        ``# Merging the component``        ``# Assigning the parent of smaller Component``        ``# as the parent of the bigger Component.``        ``if` `self``.degree[x] > ``self``.degree[y]:``            ``self``.parent[y] ``=` `x``            ``self``.degree[x] ``=` `(``self``.degree[x] ``+``                              ``self``.degree[y])``        ` `        ``else``:``            ``self``.parent[x] ``=` `y``            ``self``.degree[y] ``=` `(``self``.degree[y] ``+``                              ``self``.degree[x])``        ` `    ``# Count total Component in the Graph``    ``def` `GetTotalComponent(``self``):``    ` `        ``# To count the total Component formed``        ``# from the inserted vertex in the Graph``        ``total ``=` `set``()` `        ``# Iterate through the parent``        ``for` `itr ``in` `self``.parent:` `            ``# Add the parent of each Vertex``            ``# to the set``            ``total.add(``self``.getParent(itr))``        ` `        ``# Total Component = Total Vertexes -``        ``# Number of Vertex in the parent +``        ``# Number of Component formed from``        ``# the Vertexes inserted in the Graph``        ``return` `self``.N ``-` `len``(``self``.parent) ``+` `len``(total)` `# Solve``def` `Solve(N):` `    ``# Declaring the Dynamic Disjoint Set DS``    ``dsu ``=` `DynamicDisjointSetDS(N)` `    ``# Traversing through the Edges``    ``for` `i ``in` `range``(``0``, ``3``):` `        ``# If the Vertexes in the Edges``        ``# have same parent do nothing``        ``if` `(dsu.getParent(Edges[i][``0``]) ``=``=``            ``dsu.getParent(Edges[i][``1``])):``            ``continue` `        ``# else Do Union of both the Components.``        ``else``:``            ``dsu.Union(Edges[i][``0``], Edges[i][``1``])` `    ``# Get total Components``    ``print``(dsu.GetTotalComponent())` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:` `    ``# Total Number of Vertexes``    ``N ``=` `5``    ``Edges ``=` `[[``1``, ``2``], [``2``, ``3``], [``4``, ``3``]]` `    ``# Solve``    ``Solve(N)` `# This code is contributed by``# Rituraj Jain`

Output:

`2`

Note: If the number of vertices are even larger, we can implement the same code just by changing the data type from int to long.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up