Open In App

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:

Below is the implementation of the above approach:




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




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


Article Tags :