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

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:
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:
 

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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement
// the above approach
#include <bits/stdc++.h>
#define MOD 1000000007
  
#define int long long int
using namespace std;
  
// Disjoint Set Union
struct 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 Graph
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]) {
  
            // 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 Code
int32_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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to implement
// the above approach
import java.util.*;
  
class GFG{
  
static final int MOD = 1000000007;
  
// Disjoint Set Union
static 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 Graph
static 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 Code
public 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to implement
// the above approach
using System;
  
class GFG{
  
//static readonly int MOD = 1000000007;
  
// Disjoint Set Union
class 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 Graph
static 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 Code
public 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

chevron_right


Output: 

1

Time Complexity: O(N), where N is the number of nodes in the graph.
Auxiliary Space: O(N)
 

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.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : 29AjayKumar, Rajput-Ji