Given a Directed Graph with N vertices value from 0 to N – 1 and N – 1 Edges, the task is to count the number of edges must be reversed so that there is always a path from every node to node 0.
Examples:
Input: Below is the given graph
Output: 3
Explanation:
Input: Below is the given graph
Output: 0
Approach: The idea is to use BFS Traversal for a graph. Below are the steps:
- Create a directed graph with the direction of the edges of the given graph reversed.
- Create a queue and push node 0 in the queue.
- During BFS Traversal on the graph do the following:
- Pop the front node(say current_node) from the queue.
- Traverse the Adjacency List of current node in the reverse graph and push in those node in the queue that are not visited.
- Traverse the Adjacency List of current node in the reverse graph and push in those node in the queue that are not visited.
- The total nodes inserted in the queue in the above steps is required count of edges to be reversed because the nodes which are connected to the current node and have not been visited yet in the graph cannot be reached to node 0, therefore, we need to reverse their direction. Add the count of the nodes in the above step to the final count.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to find minimum reversals int minRev(vector<vector< int > > edges,
int n)
{ // Add all adjacent nodes to
// the node in the graph
unordered_map< int , vector< int > > graph;
unordered_map< int , vector< int > > graph_rev;
for ( int i = 0;
i < edges.size(); i++) {
int x = edges[i][0];
int y = edges[i][1];
// Insert edges in the graph
graph[x].push_back(y);
// Insert edges in the
// reversed graph
graph_rev[y].push_back(x);
}
queue< int > q;
// Create array visited to mark
// all the visited nodes
vector< int > visited(n, 0);
q.push(0);
// Stores the number of
// edges to be reversed
int ans = 0;
// BFS Traversal
while (!q.empty()) {
// Pop the current node
// from the queue
int curr = q.front();
// mark the current
// node visited
visited[curr] = 1;
// Initialize count of edges
// need to be reversed to 0
int count = 0;
q.pop();
// Push adjacent nodes in the
// reversed graph to the queue,
// if not visited
for ( int i = 0;
i < graph_rev[curr].size();
i++) {
if (!visited[graph_rev[curr][i]]) {
q.push(graph_rev[curr][i]);
}
}
// Push adjacent nodes in graph
// to the queue, if not visited
// count the number of
// nodes added to the queue
for ( int i = 0;
i < graph[curr].size();
i++) {
if (!visited[graph[curr][i]]) {
q.push(graph[curr][i]);
count++;
}
}
// Update the reverse edge
// to the final count
ans += count;
}
// Return the result
return ans;
} // Driver Code int main()
{ vector<vector< int > > edges;
// Given edges to the graph
edges = { { 0, 1 }, { 1, 3 }, { 2, 3 },
{ 4, 0 }, { 4, 5 } };
// Number of nodes
int n = 6;
// Function Call
cout << minRev(edges, n);
return 0;
} |
# Python3 program for the above approach # Function to find minimum reversals def minRev(edges, n):
# Add all adjacent nodes to
# the node in the graph
graph = dict ()
graph_rev = dict ()
for i in range ( len (edges)):
x = edges[i][ 0 ];
y = edges[i][ 1 ];
# Insert edges in the graph
if x not in graph:
graph[x] = []
graph[x].append(y);
# Insert edges in the
# reversed graph
if y not in graph_rev:
graph_rev[y] = []
graph_rev[y].append(x);
q = []
# Create array visited to mark
# all the visited nodes
visited = [ 0 for i in range (n)]
q.append( 0 );
# Stores the number of
# edges to be reversed
ans = 0 ;
# BFS Traversal
while ( len (q) ! = 0 ):
# Pop the current node
# from the queue
curr = q[ 0 ]
# mark the current
# node visited
visited[curr] = 1 ;
# Initialize count of edges
# need to be reversed to 0
count = 0 ;
q.pop( 0 );
# Push adjacent nodes in the
# reversed graph to the queue,
# if not visited
if curr in graph_rev:
for i in range ( len (graph_rev[curr])):
if ( not visited[graph_rev[curr][i]]):
q.append(graph_rev[curr][i]);
# Push adjacent nodes in graph
# to the queue, if not visited
# count the number of
# nodes added to the queue
if curr in graph:
for i in range ( len (graph[curr])):
if ( not visited[graph[curr][i]]):
q.append(graph[curr][i]);
count + = 1
# Update the reverse edge
# to the final count
ans + = count;
# Return the result
return ans;
# Driver Code if __name__ = = '__main__' :
edges = []
# Given edges to the graph
edges = [ [ 0 , 1 ], [ 1 , 3 ], [ 2 , 3 ],[ 4 , 0 ], [ 4 , 5 ] ];
# Number of nodes
n = 6 ;
# Function Call
print (minRev(edges, n))
# This code is contributed by rutvik_56 |
// C# program for the above approach using System;
using System.Collections;
using System.Collections.Generic;
class GFG{
// Function to find minimum reversals static int minRev(ArrayList edges, int n)
{ // Add all adjacent nodes to
// the node in the graph
Dictionary< int ,
ArrayList> graph = new Dictionary< int ,
ArrayList>();
Dictionary< int ,
ArrayList> graph_rev = new Dictionary< int ,
ArrayList>();
for ( int i = 0;i < edges.Count; i++)
{
int x = ( int )((ArrayList)edges[i])[0];
int y = ( int )((ArrayList)edges[i])[1];
// Insert edges in the graph
if (!graph.ContainsKey(x))
{
graph[x] = new ArrayList();
}
graph[x].Add(y);
// Insert edges in the
// reversed graph
if (!graph_rev.ContainsKey(y))
{
graph_rev[y] = new ArrayList();
}
graph_rev[y].Add(x);
}
Queue q = new Queue();
// Create array visited to mark
// all the visited nodes
ArrayList visited = new ArrayList();
for ( int i = 0; i < n + 1; i++)
{
visited.Add( false );
}
q.Enqueue(0);
// Stores the number of
// edges to be reversed
int ans = 0;
// BFS Traversal
while (q.Count != 0)
{
// Pop the current node
// from the queue
int curr = ( int )q.Peek();
// mark the current
// node visited
visited[curr] = true ;
// Initialize count of edges
// need to be reversed to 0
int count = 0;
q.Dequeue();
// Enqueue adjacent nodes in the
// reversed graph to the queue,
// if not visited
if (graph_rev.ContainsKey(curr))
{
for ( int i = 0;
i < graph_rev[curr].Count;
i++)
{
if (!( bool )visited[( int )(
(ArrayList)graph_rev[curr])[i]])
{
q.Enqueue(( int )(
(ArrayList)graph_rev[curr])[i]);
}
}
}
// Enqueue adjacent nodes in graph
// to the queue, if not visited
// count the number of
// nodes added to the queue
if (graph.ContainsKey(curr))
{
for ( int i = 0;
i < ((ArrayList)graph[curr]).Count;
i++)
{
if (!( bool )visited[( int )(
(ArrayList)graph[curr])[i]])
{
q.Enqueue(( int )(
(ArrayList)graph[curr])[i]);
count++;
}
}
}
// Update the reverse edge
// to the final count
ans += count;
}
// Return the result
return ans;
} // Driver Code public static void Main( string []args)
{ ArrayList edges = new ArrayList(){
new ArrayList(){ 0, 1 },
new ArrayList(){ 1, 3 },
new ArrayList(){ 2, 3 },
new ArrayList(){ 4, 0 },
new ArrayList(){ 4, 5 } };
// Number of nodes
int n = 6;
// Function Call
Console.Write(minRev(edges, n));
} } // This code is contributed by pratham76 |
// Java program for the above approach import java.io.*;
import java.util.*;
class GFG {
// Function to find minimum reversals
static int minRev(ArrayList<ArrayList<Integer> > edges,
int n)
{
// Add all adjacent nodes to the node in the graph
Map<Integer, ArrayList<Integer> > graph
= new HashMap<>();
Map<Integer, ArrayList<Integer> > graphRev
= new HashMap<>();
for (ArrayList<Integer> edge : edges) {
int x = edge.get( 0 );
int y = edge.get( 1 );
// Insert edges in the graph
if (!graph.containsKey(x)) {
graph.put(x, new ArrayList<>());
}
graph.get(x).add(y);
// Insert edges in the reversed graph
if (!graphRev.containsKey(y)) {
graphRev.put(y, new ArrayList<>());
}
graphRev.get(y).add(x);
}
Queue<Integer> q = new LinkedList<>();
// Create boolean array visited to mark all the
// visited nodes
boolean [] visited = new boolean [n + 1 ];
q.add( 0 );
// Stores the number of edges to be reversed
int ans = 0 ;
// BFS Traversal
while (!q.isEmpty()) {
// Pop the current node from the queue
int curr = q.peek();
// mark the current node visited
visited[curr] = true ;
// Initialize count of edges need to be reversed
// to 0
int count = 0 ;
q.remove();
// Enqueue adjacent nodes in the reversed graph
// to the queue, if not visited
if (graphRev.containsKey(curr)) {
for ( int node : graphRev.get(curr)) {
if (!visited[node]) {
q.add(node);
}
}
}
// Enqueue adjacent nodes in graph to the queue,
// if not visited count the number of nodes
// added to the queue
if (graph.containsKey(curr)) {
for ( int node : graph.get(curr)) {
if (!visited[node]) {
q.add(node);
count++;
}
}
}
// Update the reverse edge to the final count
ans += count;
}
// Return the result
return ans;
}
public static void main(String[] args)
{
ArrayList<ArrayList<Integer> > edges
= new ArrayList<>();
edges.add( new ArrayList<>(Arrays.asList( 0 , 1 )));
edges.add( new ArrayList<>(Arrays.asList( 1 , 3 )));
edges.add( new ArrayList<>(Arrays.asList( 2 , 3 )));
edges.add( new ArrayList<>(Arrays.asList( 4 , 0 )));
edges.add( new ArrayList<>(Arrays.asList( 4 , 5 )));
// Number of nodes
int n = 6 ;
// Function Call
System.out.println(minRev(edges, n));
}
} // This code is contributed by lokeshmvs21. |
// JavaScript program for the above approach // Function to find minimum reversals function minRev(edges, n) {
// Add all adjacent nodes to // the node in the graph let graph = new Map();
let graph_rev = new Map();
for (let i = 0; i < edges.length; i++) {
let x = edges[i][0]; let y = edges[i][1]; // Insert edges in the graph if (!graph.has(x)) {
graph.set(x, []);
} graph.get(x).push(y); // Insert edges in the // reversed graph if (!graph_rev.has(y)) {
graph_rev.set(y, []);
} graph_rev.get(y).push(x); } let q = []; // Create array visited to mark // all the visited nodes let visited = new Array(n).fill(0);
q.push(0); // Stores the number of // edges to be reversed let ans = 0; // BFS Traversal while (q.length != 0) {
// Pop the current node // from the queue let curr = q[0]; // mark the current // node visited visited[curr] = 1; // Initialize count of edges // need to be reversed to 0 let count = 0; q.shift(); // Push adjacent nodes in the // reversed graph to the queue, // if not visited if (graph_rev.has(curr)) {
for (let i = 0; i < graph_rev.get(curr).length; i++) {
if (!visited[graph_rev.get(curr)[i]]) {
q.push(graph_rev.get(curr)[i]);
}
}
} // Push adjacent nodes in graph // to the queue, if not visited // count the number of // nodes added to the queue if (graph.has(curr)) {
for (let i = 0; i < graph.get(curr).length; i++) {
if (!visited[graph.get(curr)[i]]) {
q.push(graph.get(curr)[i]);
count += 1;
}
}
} // Update the reverse edge // to the final count ans += count; } // Return the result return ans;
} // Driver Code let edges = []; // Given edges to the graph edges = [[0, 1], [1, 3], [2, 3], [4, 0], [4, 5]]; // Number of nodes let n = 6; // Function Call console.log(minRev(edges, n)); |
3
Time Complexity: O(V+E) where V is the number of vertices, E is the number of edges.
Auxiliary Space: O(V) where V is the number of vertices.