Open In App

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

Last Updated : 20 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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




// 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;
}


Java




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


Python3




# Python3 program to implement
# the above approach
MOD = 1000000007
 
# Disjoint Set Union
class 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 Graph
def 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 Code
if __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#




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


Javascript




<script>
 
// Javascript program to implement
// the above approach
 
var MOD = 1000000007;
 
// Stores the parent
// of each node
var parent = [];
// Storing maximum value
// in each component
var maximum_node = [];
// Stores the minimum value
// in each component
var minimum_node = [];
// Stores the visited nodes
var visited = [];
// Function to initialize the
// values in vectors
function 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 component
function 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 components
function 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 Graph
function 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 Code
var N = 7;
init(N);
// Insert edges
unite(1, 5);
unite(2, 4);
unite(3, 4);
document.write(minimumEdgesToBeAdded(N));
 
 
</script>


Output: 

1

 

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



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads