Minimum number of Edges to be added to a Graph to satisfy the given condition - GeeksforGeeks

30 Jun, 2021
Given a graph consisting of N nodes numbered from 0 to N – 1 and M edges in the form of pairs {a, b}, the task is to find the minimum number of edges to be added to the graph such that if there exists a path from any node a to node b, then there should be paths from node a to nodes [ a + 1, a + 2, a + 3, ..., b – 1] as well.
Examples:  
Input: N = 7, M = 3, Edges[][] = {{1, 5}, {2, 4}, {3, 4}} Output: 1 Explanation: There is a path from 1 to 5. So there should be paths from 1 to 2, 3 and 4 as well. Adding an edge {1, 2} will be sufficient to reach the other two nodes of the graph.
Input: N = 8, M = 3 Edges[][] = {{1, 2}, {2, 3}, {3, 4}} Output: 0  
Approach:The idea is to use a Disjoint Set or Union find. Each component in the disjoint set should have consecutive nodes. This can be done by maintaining maximum_node[] and minimum_node[] arrays to store the maximum and minimum value of nodes in each component respectively. Follow the steps below to solve the problem:
Create a structure for the disjoint set union.
Initialize the answer as 0 and iterate over all the nodes in the graph to get the component of the current node.
If the component is not visited, then mark it as visited.
Now, Iterate from minimum value to maximum value of that component and check if the the nodes are in the same component with the current node or not and combine them into one component and increment the answer by 1.
Finally, print the answer.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program to implement// the above approach#include <bits/stdc++.h>#define MOD 1000000007 #define int long long intusing namespace std; // Disjoint Set Unionstruct dsu {     // Stores the parent    // of each node    vector<int> parent;     // Storing maximum value    // in each component    vector<int> maximum_node;     // Stores the minimum value    // in each component    vector<int> minimum_node;     // Stores the visited nodes    vector<int> visited;     // Function to initialize the    // values in vectors    void init(int n)    {        // Initialize the size of        // vectors as n        parent.resize(n);        maximum_node.resize(n);        minimum_node.resize(n);        visited.resize(n);         for (int i = 0; i < n; i++) {             // Initially every component            // has only one node            parent[i] = i;            maximum_node[i] = i;            minimum_node[i] = i;             // Mark unvisited            visited[i] = 0;        }    }     // Function to get identifier node    // (superparent) for each component    int getsuperparent(int x)    {         // If parent of a node is that        // node itself then the node is        // superparent of that component        return x == parent[x]                   ? x                   : parent[x]                     = getsuperparent(parent[x]);    }     // Function to perform union of two    // different components    void unite(int x, int y)    {         int superparent_x = getsuperparent(x);        int superparent_y = getsuperparent(y);         // Set superparent of y as the        // parent of superparent of x        parent[superparent_x] = superparent_y;         // Update the maximum node        // in the component containing y        maximum_node[superparent_y]            = max(maximum_node[superparent_y],                  maximum_node[superparent_x]);         // Update the minimum node        // in the component containing y        minimum_node[superparent_y]            = min(minimum_node[superparent_y],                  minimum_node[superparent_x]);    }} G; // Function to find the minimum number// of edges to be added to the Graphint minimumEdgesToBeAdded(int n){    // Stores the answer    int answer = 0;     // Iterate over all nodes    for (int i = 0; i < n; i++) {         // Get the superparent of        // the current node        int temp = G.getsuperparent(i);         // If the node is not visited        if (!G.visited[temp]) {             // Set the node as visited            G.visited[temp] = 1;             // Iterate from the minimum            // value to maximum value in            // the current component            for (int j = G.minimum_node[temp];                 j <= G.maximum_node[temp]; j++) {                 // If the nodes are in                // different components                if (G.getsuperparent(j)                    != G.getsuperparent(i)) {                     // Unite them                    G.unite(i, j);                     // Increment the answer                    answer++;                }            }        }    }     // Return the answer    return answer;} // Driver Codeint32_t main(){    int N = 7, M = 3;     G.init(N);     // Insert edges    G.unite(1, 5);    G.unite(2, 4);    G.unite(3, 4);     cout << minimumEdgesToBeAdded(N);    return 0;}
// Java program to implement// the above approachimport java.util.*; class GFG{ static final int MOD = 1000000007; // Disjoint Set Unionstatic class dsu{    public dsu(){}     // Stores the parent    // of each node    int[] parent;     // Storing maximum value    // in each component    int[] maximum_node;     // Stores the minimum value    // in each component    int[] minimum_node;     // Stores the visited nodes    int[] visited;     // Function to initialize the    // values in vectors    void init(int n)    {                 // Initialize the size of        // vectors as n        parent = new int[n];        maximum_node = new int[n];        minimum_node = new int[n];        visited = new int[n];         for(int i = 0; i < n; i++)        {                         // Initially every component            // has only one node            parent[i] = i;            maximum_node[i] = i;            minimum_node[i] = i;             // Mark unvisited            visited[i] = 0;        }    }     // Function to get identifier node    // (superparent) for each component    int getsuperparent(int x)    {         // If parent of a node is that        // node itself then the node is        // superparent of that component        if(x == parent[x])            return x;        else        {            parent[x] = getsuperparent(parent[x]);            return parent[x];        }    }     // Function to perform union of two    // different components    void unite(int x, int y)    {        int superparent_x = getsuperparent(x);        int superparent_y = getsuperparent(y);         // Set superparent of y as the        // parent of superparent of x        parent[superparent_x] = superparent_y;         // Update the maximum node        // in the component containing y        maximum_node[superparent_y] = Math.max(        maximum_node[superparent_y],        maximum_node[superparent_x]);         // Update the minimum node        // in the component containing y        minimum_node[superparent_y] = Math.min(        minimum_node[superparent_y],        minimum_node[superparent_x]);    }}; static dsu G = new dsu(); // Function to find the minimum number// of edges to be added to the Graphstatic int minimumEdgesToBeAdded(int n){         // Stores the answer    int answer = 0;     // Iterate over all nodes    for(int i = 0; i < n; i++)    {                 // Get the superparent of        // the current node        int temp = G.getsuperparent(i);         // If the node is not visited        if (G.visited[temp] == 0)        {                         // Set the node as visited            G.visited[temp] = 1;             // Iterate from the minimum            // value to maximum value in            // the current component            for(int j = G.minimum_node[temp];                   j <= G.maximum_node[temp]; j++)            {                                 // If the nodes are in                // different components                if (G.getsuperparent(j) !=                    G.getsuperparent(i))                {                                         // Unite them                    G.unite(i, j);                     // Increment the answer                    answer++;                }            }        }    }         // Return the answer    return answer;} // Driver Codepublic static void main(String[] args){    int N = 7;     G.init(N);     // Insert edges    G.unite(1, 5);    G.unite(2, 4);    G.unite(3, 4);     System.out.print(minimumEdgesToBeAdded(N));}} // This code is contributed by 29AjayKumar
# Python3 program to implement# the above approachMOD = 1000000007 # Disjoint Set Unionclass dsu:     # Function to initialize the    # values in vectors    def __init__(self, n: int) -> None:                 # Stores the parent        # of each node        self.parent = [i for i in range(n)]                 # Storing maximum value        # in each component        self.maximum_node = [i for i in range(n)]                 # Stores the minimum value        # in each component        self.minimum_node = [i for i in range(n)]                 # Stores the visited nodes        self.visited = [0] * n     # Function to get identifier node    # (superparent) for each component    def getsuperparent(self, x: int) -> int:                 # If parent of a node is that        # node itself then the node is        # superparent of that component        if x == self.parent[x]:            return x        else:            self.parent[x] = self.getsuperparent(                self.parent[x])            return self.parent[x]     # Function to perform union of two    # different components    def unite(self, x: int, y: int) -> None:         superparent_x = self.getsuperparent(x)        superparent_y = self.getsuperparent(y)         # Set superparent of y as the        # parent of superparent of x        self.parent[superparent_x] = superparent_y         # Update the maximum node        # in the component containing y        self.maximum_node[superparent_y] = max(            self.maximum_node[superparent_y],            self.maximum_node[superparent_x])         # Update the minimum node        # in the component containing y        self.minimum_node[superparent_y] = min(            self.minimum_node[superparent_y],            self.minimum_node[superparent_x]) # Function to find the minimum number# of edges to be added to the Graphdef minimumEdgesToBeAdded(n: int) -> int:     global G     # Stores the answer    answer = 0     # Iterate over all nodes    for i in range(n):         # Get the superparent of        # the current node        temp = G.getsuperparent(i)         # If the node is not visited        if (not G.visited[temp]):             # Set the node as visited            G.visited[temp] = 1             # Iterate from the minimum            # value to maximum value in            # the current component            for j in range(G.minimum_node[temp],                           G.maximum_node[temp] + 1):                                                # If the nodes are in                # different components                if (G.getsuperparent(j) !=                    G.getsuperparent(i)):                     # Unite them                    G.unite(i, j)                     # Increment the answer                    answer += 1     # Return the answer    return answer # Driver Codeif __name__ == "__main__":     N = 7    M = 3     G = dsu(N)     # Insert edges    G.unite(1, 5)    G.unite(2, 4)    G.unite(3, 4)         print(minimumEdgesToBeAdded(N)) # This code is contributed by sanjeev2552
// C# program to implement// the above approachusing System; class GFG{ //static readonly int MOD = 1000000007; // Disjoint Set Unionclass dsu{    public dsu(){}     // Stores the parent    // of each node    public int[] parent;     // Storing maximum value    // in each component    public int[] maximum_node;     // Stores the minimum value    // in each component    public int[] minimum_node;     // Stores the visited nodes    public int[] visited;     // Function to initialize the    // values in vectors    public void init(int n)    {                 // Initialize the size of        // vectors as n        parent = new int[n];        maximum_node = new int[n];        minimum_node = new int[n];        visited = new int[n];         for(int i = 0; i < n; i++)        {                         // Initially every component            // has only one node            parent[i] = i;            maximum_node[i] = i;            minimum_node[i] = i;             // Mark unvisited            visited[i] = 0;        }    }     // Function to get identifier node    // (superparent) for each component    public int getsuperparent(int x)    {         // If parent of a node is that        // node itself then the node is        // superparent of that component        if(x == parent[x])            return x;        else        {            parent[x] = getsuperparent(parent[x]);            return parent[x];        }    }     // Function to perform union of two    // different components    public void unite(int x, int y)    {        int superparent_x = getsuperparent(x);        int superparent_y = getsuperparent(y);         // Set superparent of y as the        // parent of superparent of x        parent[superparent_x] = superparent_y;         // Update the maximum node        // in the component containing y        maximum_node[superparent_y] = Math.Max(        maximum_node[superparent_y],        maximum_node[superparent_x]);         // Update the minimum node        // in the component containing y        minimum_node[superparent_y] = Math.Min(        minimum_node[superparent_y],        minimum_node[superparent_x]);    }}; static dsu G = new dsu(); // Function to find the minimum number// of edges to be added to the Graphstatic int minimumEdgesToBeAdded(int n){         // Stores the answer    int answer = 0;     // Iterate over all nodes    for(int i = 0; i < n; i++)    {                 // Get the superparent of        // the current node        int temp = G.getsuperparent(i);         // If the node is not visited        if (G.visited[temp] == 0)        {                         // Set the node as visited            G.visited[temp] = 1;             // Iterate from the minimum            // value to maximum value in            // the current component            for(int j = G.minimum_node[temp];                   j <= G.maximum_node[temp]; j++)            {                                 // If the nodes are in                // different components                if (G.getsuperparent(j) !=                    G.getsuperparent(i))                {                                         // Unite them                    G.unite(i, j);                     // Increment the answer                    answer++;                }            }        }    }         // Return the answer    return answer;} // Driver Codepublic static void Main(String[] args){    int N = 7;     G.init(N);     // Insert edges    G.unite(1, 5);    G.unite(2, 4);    G.unite(3, 4);     Console.Write(minimumEdgesToBeAdded(N));}} // This code is contributed by Rajput-Ji
<script> // Javascript program to implement// the above approach var MOD = 1000000007; // Stores the parent// of each nodevar parent = [];// Storing maximum value// in each componentvar maximum_node = [];// Stores the minimum value// in each componentvar minimum_node = [];// Stores the visited nodesvar visited = [];// Function to initialize the// values in vectorsfunction init(n){         // Initialize the size of    // vectors as n    parent = Array(n);    maximum_node = Array(n);    minimum_node = Array(n);    visited = Array(n);    for(var i = 0; i < n; i++)    {                 // Initially every component        // has only one node        parent[i] = i;        maximum_node[i] = i;        minimum_node[i] = i;        // Mark unvisited        visited[i] = 0;    }}// Function to get identifier node// (superparent) for each componentfunction getsuperparent(x){    // If parent of a node is that    // node itself then the node is    // superparent of that component    if(x == parent[x])        return x;    else    {        parent[x] = getsuperparent(parent[x]);        return parent[x];    }}// Function to perform union of two// different componentsfunction unite(x, y){    var superparent_x = getsuperparent(x);    var superparent_y = getsuperparent(y);    // Set superparent of y as the    // parent of superparent of x    parent[superparent_x] = superparent_y;    // Update the maximum node    // in the component containing y    maximum_node[superparent_y] = Math.max(        maximum_node[superparent_y],        maximum_node[superparent_x]);    // Update the minimum node    // in the component containing y    minimum_node[superparent_y] = Math.min(        minimum_node[superparent_y],        minimum_node[superparent_x]);} // Function to find the minimum number// of edges to be added to the Graphfunction minimumEdgesToBeAdded(n){         // Stores the answer    var answer = 0;     // Iterate over all nodes    for(var i = 0; i < n; i++)    {                 // Get the superparent of        // the current node        var temp = getsuperparent(i);         // If the node is not visited        if (visited[temp] == 0)        {                         // Set the node as visited            visited[temp] = 1;             // Iterate from the minimum            // value to maximum value in            // the current component            for(var j = minimum_node[temp];                   j <= maximum_node[temp]; j++)            {                                 // If the nodes are in                // different components                if (getsuperparent(j) !=                    getsuperparent(i))                {                                         // Unite them                    unite(i, j);                     // Increment the answer                    answer++;                }            }        }    }         // Return the answer    return answer;} // Driver Codevar N = 7;init(N);// Insert edgesunite(1, 5);unite(2, 4);unite(3, 4);document.write(minimumEdgesToBeAdded(N));  </script>
1
 
Time Complexity: O(N), where N is the number of nodes in the graph.Auxiliary Space: O(N) 
29AjayKumar
Rajput-Ji
sanjeev2552
rrrtnx
disjoint-set
union-find
Data Structures
Graph
Data Structures
Graph
union-find
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Introduction to Tree Data Structure
Program to implement Singly Linked List in C++ using class
TCS NQT Coding Sheet
Hash Functions and list/types of Hash functions
Building an undirected graph and finding shortest path using Dictionaries in Python
Breadth First Search or BFS for a Graph
Dijkstra's shortest path algorithm | Greedy Algo-7
Depth First Search or DFS for a Graph
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2