Given a directed graph of n vertices and m edges, the task is to find the minimum number of edges required to make the graph strongly connected.
Note: In a directed graph, a Strongly Connected Component is a subset of vertices where every vertex in the subset is reachable from every other vertex in the same subset by traversing the directed edges
Examples:
Input: n = 3, m = 3, source[] = [1, 2, 1], destination[] = [2, 3, 3]
Output: 1
Explanation: Adding a directed edge joining the pair of vertices {3, 1} makes the graph strongly connected. Hence, the minimum number of edges required is 1.
Below is the illustration of the above example:Input: n = 5, m = 5, source[] = [1, 3, 1, 3, 4], destination[] = [2, 2, 3, 4, 5]
Output: 2
Explanation: Adding 2 directed edges to join the following pair of vertices [2, 1] and [5, 2] makes the graph strongly connected. Hence, the minimum number of edges required is 2.
Approach:
For a graph to be strongly connected, each vertex must have an in-degree and an out-degree of at least 1. Thus, the maximum number of incoming edges and the outgoing edges required to make the graph strongly connected is the minimum edges required to make it strongly connected. To do so, find the count of in-degrees and out-degrees of each vertex of the graph using DFS. If the in-degree or out-degree of a vertex is greater than 1, then consider it as only 1, and count the total in-degree and out-degree of the graph. The minimum edges required to make the graph strongly connected is max(N-total In-degree, N-total Out-degree).
Below is the implementation of the above approach:
#include <bits/stdc++.h>
using namespace std;
// Perform DFS to count the in and out degree of graph
void dfs(int ind, vector<vector<int>> &adj, vector<int> &vis,
vector<int> &inDeg, vector<int> &outDeg) {
// Mark the source as visited
vis[ind] = 1;
// Traversing adjacent nodes
for (auto v : adj[ind]) {
// Mark out-degree as 1
outDeg[ind] = 1;
// Mark in-degree as 1
inDeg[v] = 1;
// If not visited
if (vis[v] == 0)
// DFS Traversal on adjacent vertex
dfs(v, adj, vis, inDeg, outDeg);
}
}
// Function to return minimum number of edges
// required to make the graph strongly connected
int findMinimumEdges(vector<int> &source,
vector<int> &dest, int n, int m) {
// to store the adjacency List
vector<vector<int>> adj(n + 1);
// Create the Adjacency List
for (int i = 0; i < m; i++)
adj[source[i]].push_back(dest[i]);
// Initialize the in-degree array
vector<int> inDeg(n + 1, 0);
// Initialize the out-degree array
vector<int> outDeg(n + 1, 0);
// Initialize the visited array
vector<int> vis(n + 1, 0);
// Perform DFS from all unvisited vertices
for (int i = 1; i <= n; ++i)
if (vis[i] == 0)
dfs(i, adj, vis, inDeg, outDeg);
// To store the result
int minEdges = 0;
// To store total count of in-degree
// and out-degree
int totalIn = 0;
int totalOut = 0;
// Find total in-degree
// and out-degree
for (int i = 1; i <= n; i++) {
if (inDeg[i] == 1)
totalIn++;
if (outDeg[i] == 1)
totalOut++;
}
// Calculate the minimum
// edges required
minEdges = max(n - totalIn, n - totalOut);
// Return the minimum edges
return minEdges;
}
int main() {
int n = 5, m = 5;
vector<int> source = {1, 3, 1, 3, 4};
vector<int> dest = {2, 2, 3, 4, 5};
cout << findMinimumEdges(source, dest, n, m);
return 0;
}
import java.util.*;
class GfG {
// Perform DFS to count the in and out degree of graph
static void dfs(int ind, List<List<Integer>> adj, int[] vis,
int[] inDeg, int[] outDeg) {
// Mark the source as visited
vis[ind] = 1;
// Traversing adjacent nodes
for (int v : adj.get(ind)) {
// Mark out-degree as 1
outDeg[ind] = 1;
// Mark in-degree as 1
inDeg[v] = 1;
// If not visited
if (vis[v] == 0)
// DFS Traversal on adjacent vertex
dfs(v, adj, vis, inDeg, outDeg);
}
}
// Function to return minimum number of edges
// required to make the graph strongly connected
static int findMinimumEdges(List<Integer> source,
List<Integer> dest, int n, int m) {
// to store the adjacency List
List<List<Integer>> adj = new ArrayList<>();
for (int i = 0; i <= n; i++)
adj.add(new ArrayList<>());
// Create the Adjacency List
for (int i = 0; i < m; i++)
adj.get(source.get(i)).add(dest.get(i));
// Initialize the in-degree array
int[] inDeg = new int[n + 1];
// Initialize the out-degree array
int[] outDeg = new int[n + 1];
// Initialize the visited array
int[] vis = new int[n + 1];
// Perform DFS from all unvisited vertices
for (int i = 1; i <= n; ++i)
if (vis[i] == 0)
dfs(i, adj, vis, inDeg, outDeg);
// To store the result
int minEdges = 0;
// To store total count of in-degree
// and out-degree
int totalIn = 0;
int totalOut = 0;
// Find total in-degree
// and out-degree
for (int i = 1; i <= n; i++) {
if (inDeg[i] == 1)
totalIn++;
if (outDeg[i] == 1)
totalOut++;
}
// Calculate the minimum
// edges required
minEdges = Math.max(n - totalIn, n - totalOut);
// Return the minimum edges
return minEdges;
}
public static void main(String[] args) {
int n = 5, m = 5;
List<Integer> source = Arrays.asList(1, 3, 1, 3, 4);
List<Integer> dest = Arrays.asList(2, 2, 3, 4, 5);
System.out.println(findMinimumEdges(source, dest, n, m));
}
}
# Perform DFS to count the in and out degree of graph
def dfs(ind, adj, vis, inDeg, outDeg):
# Mark the source as visited
vis[ind] = 1
# Traversing adjacent nodes
for v in adj[ind]:
# Mark out-degree as 1
outDeg[ind] = 1
# Mark in-degree as 1
inDeg[v] = 1
# If not visited
if vis[v] == 0:
# DFS Traversal on adjacent vertex
dfs(v, adj, vis, inDeg, outDeg)
# Function to return minimum number of edges
# required to make the graph strongly connected
def findMinimumEdges(source, dest, n, m):
# to store the adjacency List
adj = [[] for _ in range(n + 1)]
# Create the Adjacency List
for i in range(m):
adj[source[i]].append(dest[i])
# Initialize the in-degree array
inDeg = [0] * (n + 1)
# Initialize the out-degree array
outDeg = [0] * (n + 1)
# Initialize the visited array
vis = [0] * (n + 1)
# Perform DFS from all unvisited vertices
for i in range(1, n + 1):
if vis[i] == 0:
dfs(i, adj, vis, inDeg, outDeg)
# To store the result
minEdges = 0
# To store total count of in-degree
# and out-degree
totalIn = 0
totalOut = 0
# Find total in-degree
# and out-degree
for i in range(1, n + 1):
if inDeg[i] == 1:
totalIn += 1
if outDeg[i] == 1:
totalOut += 1
# Calculate the minimum
# edges required
minEdges = max(n - totalIn, n - totalOut)
# Return the minimum edges
return minEdges
if __name__ == "__main__":
n = 5
m = 5
source = [1, 3, 1, 3, 4]
dest = [2, 2, 3, 4, 5]
print(findMinimumEdges(source, dest, n, m))
using System;
using System.Collections.Generic;
class GfG {
// Perform DFS to count the in and out degree of graph
static void Dfs(int ind, List<int>[] adj, int[] vis,
int[] inDeg, int[] outDeg) {
// Mark the source as visited
vis[ind] = 1;
// Traversing adjacent nodes
foreach (var v in adj[ind]) {
// Mark out-degree as 1
outDeg[ind] = 1;
// Mark in-degree as 1
inDeg[v] = 1;
// If not visited
if (vis[v] == 0)
// DFS Traversal on adjacent vertex
Dfs(v, adj, vis, inDeg, outDeg);
}
}
// Function to return minimum number of edges
// required to make the graph strongly connected
static int FindMinimumEdges(List<int> source,
List<int> dest, int n, int m) {
// to store the adjacency List
List<int>[] adj = new List<int>[n + 1];
for (int i = 0; i <= n; i++)
adj[i] = new List<int>();
// Create the Adjacency List
for (int i = 0; i < m; i++)
adj[source[i]].Add(dest[i]);
// Initialize the in-degree array
int[] inDeg = new int[n + 1];
// Initialize the out-degree array
int[] outDeg = new int[n + 1];
// Initialize the visited array
int[] vis = new int[n + 1];
// Perform DFS from all unvisited vertices
for (int i = 1; i <= n; ++i)
if (vis[i] == 0)
Dfs(i, adj, vis, inDeg, outDeg);
// To store the result
int minEdges = 0;
// To store total count of in-degree
// and out-degree
int totalIn = 0;
int totalOut = 0;
// Find total in-degree
// and out-degree
for (int i = 1; i <= n; i++) {
if (inDeg[i] == 1)
totalIn++;
if (outDeg[i] == 1)
totalOut++;
}
// Calculate the minimum
// edges required
minEdges = Math.Max(n - totalIn, n - totalOut);
// Return the minimum edges
return minEdges;
}
static void Main(string[] args) {
int n = 5, m = 5;
List<int> source = new List<int> {1, 3, 1, 3, 4};
List<int> dest = new List<int> {2, 2, 3, 4, 5};
Console.WriteLine(FindMinimumEdges(source, dest, n, m));
}
}
// Perform DFS to count the in and out degree of graph
function dfs(ind, adj, vis, inDeg, outDeg) {
// Mark the source as visited
vis[ind] = 1;
// Traversing adjacent nodes
for (let v of adj[ind]) {
// Mark out-degree as 1
outDeg[ind] = 1;
// Mark in-degree as 1
inDeg[v] = 1;
// If not visited
if (vis[v] === 0)
// DFS Traversal on adjacent vertex
dfs(v, adj, vis, inDeg, outDeg);
}
}
// Function to return minimum number of edges
// required to make the graph strongly connected
function findMinimumEdges(source, dest, n, m) {
// to store the adjacency List
const adj = Array.from({ length: n + 1 }, () => []);
// Create the Adjacency List
for (let i = 0; i < m; i++)
adj[source[i]].push(dest[i]);
// Initialize the in-degree array
const inDeg = Array(n + 1).fill(0);
// Initialize the out-degree array
const outDeg = Array(n + 1).fill(0);
// Initialize the visited array
const vis = Array(n + 1).fill(0);
// Perform DFS from all unvisited vertices
for (let i = 1; i <= n; i++)
if (vis[i] === 0)
dfs(i, adj, vis, inDeg, outDeg);
// To store the result
let minEdges = 0;
// To store total count of in-degree
// and out-degree
let totalIn = 0;
let totalOut = 0;
// Find total in-degree
// and out-degree
for (let i = 1; i <= n; i++) {
if (inDeg[i] === 1)
totalIn++;
if (outDeg[i] === 1)
totalOut++;
}
// Calculate the minimum
// edges required
minEdges = Math.max(n - totalIn, n - totalOut);
// Return the minimum edges
return minEdges;
}
const n = 5, m = 5;
const source = [1, 3, 1, 3, 4];
const dest = [2, 2, 3, 4, 5];
console.log(findMinimumEdges(source, dest, n, m));
Output
2
Time Complexity: O(n + m) as the time time complexity of DFS is O(V + E) where, V is vertices and E is edges.
Auxiliary Space: O(n)