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: 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 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> |
1
Time Complexity: O(N), where N is the number of nodes in the graph.
Auxiliary Space: O(N)
Please Login to comment...