Minimum edges to reverse to make path from a source to a destination
Given a directed graph with n nodes and m edges. A source node and a destination node are also given, we need to find how many edges we need to reverse in order to make at least 1 path from the source node to the destination node.
Note: In case there is no way then return -1.
Examples:
Input: n = 7, src = 0, dst = 6
edges[][] = [ [0, 1], [2, 1], [2, 3], [6, 3], [6, 4], [4, 5], [5, 1] ]
Output: 2
Explanation: In above graph there are two paths from node 0 to node 6:
0 -> 1 -> 2 -> 3 -> 6
0 -> 1 -> 5 -> 4 -> 6
For the first path, two edges need to be reversed, and for second path, three edges need to be reversed, thus the minimum edges to be reversed is 2.Input: n = 4, src = 1, dst = 4
edges[][] = [ [1, 2], [2, 3], [3, 4] ]
Output: 0
Explanation: One path already exists between node 1 to 4: 1 -> 2 -> 3 -> 4. Thus no nodes need to be reversed.
[Naive Approach] - Finding All Paths - Exponential Time and O(n ^ 2) Space
We can use recursion to systematically explore all possible paths in a directed graph, taking into account edge directions and using memoization to optimize the process.
Follow the below given steps:
- Build an adjacency list representation of the graph, considering both forward and backward edges.
- For each directed edge in the input
edges
, create a forward edge (+1) from the source to the destination and a backward edge (-1) from the destination to the source. - Initialize an array
v
to keep track of visited nodes, initializedp
for memoization, and set the starting point for calculating the minimum edge reversals. - Recursive Solver (
solve
method):- It recursively explores the graph while considering forward and backward edges.
- Base cases: Checks for visited nodes or reaching the destination node.
- Memoization: Stores and retrieves results to avoid redundant calculations.
- Exploration: Considers both forward and backward edges, updating the minimum edge reversals required.
- Backtracking: Marks the current node as unvisited after exploration.
- Final Result and Handling Impossible Paths:
- The method returns the minimum edge reversals from the
solve
method. - If the result is a large negative value, it means no valid path exists, so -1 is returned.
- Otherwise, it returns the minimum edge reversals needed to reach the destination from the source.
- The method returns the minimum edge reversals from the
Below is given the implementation:
#include <bits/stdc++.h>
using namespace std;
// Function to find the minimum cost required to
// run m tasks on n cores is replaced by edge reversal logic
int solve(map<int, vector<pair<int, int>>> &mp,
vector<int> &v, string str, int src, int dst, map<string, int> &dp) {
if(v[src] == 1)
return INT_MAX - 1000;
if(src == dst)
return 0;
string _key = str + "-" + to_string(src);
if(dp.find(_key) != dp.end())
return dp[_key];
v[src] = 1;
int minStep = INT_MAX - 1000;
if(mp.find(src) != mp.end()){
for(auto key : mp[src]){
string temp = str + to_string(key.first);
if(key.second == -1){
minStep = min(minStep, 1 +
solve(mp, v, temp, key.first, dst, dp));
}
else{
minStep = min(minStep,
solve(mp, v, temp, key.first, dst, dp));
}
}
}
v[src] = -1;
dp[_key] = minStep;
return minStep;
}
// Function to find the minimum number of edge reversals
int minimumEdgeReversal(vector<vector<int>> &edges,
int n, int src, int dst) {
map<int, vector<pair<int, int>>> mp;
for(auto edge : edges) {
if(mp.find(edge[0]) != mp.end()) {
mp[edge[0]].push_back({edge[1], 1});
}
else {
vector<pair<int, int>> l;
l.push_back({edge[1], 1});
mp[edge[0]] = l;
}
if(mp.find(edge[1]) != mp.end()) {
mp[edge[1]].push_back({edge[0], -1});
}
else {
vector<pair<int, int>> l;
l.push_back({edge[0], -1});
mp[edge[1]] = l;
}
}
// visited
vector<int> v(n+1, -1);
map<string, int> dp;
int step = solve(mp, v, to_string(src), src, dst, dp);
return (step == INT_MAX - 1000 ? -1 : step);
}
int main() {
vector<vector<int>> edgeList = { {0, 1}, {2, 1}, {2, 3}, {6, 3}, {6, 4}, {4, 5}, {5, 1} };
int n = 7, src = 0, dst = 6;
cout << minimumEdgeReversal(edgeList, n, src, dst);
return 0;
}
// Function to find the minimum cost required
// to run m tasks on n cores
import java.util.*;
class GfG {
static int solve(Map<Integer, List<Pair> > map, int[] v,
String str, int src, int dst, Map<String, Integer> dp) {
if (v[src] == 1)
return Integer.MAX_VALUE - 1000;
if (src == dst)
return 0;
String _key = str + "-" + src;
if (dp.containsKey(_key))
return dp.get(_key);
v[src] = 1;
int minStep = Integer.MAX_VALUE - 1000;
if (map.containsKey(src)) {
for (Pair key : map.get(src)) {
String temp = str + key.node;
if (key.dir == -1) {
minStep = Math.min(minStep,
1 + solve(map, v, temp, key.node, dst, dp));
}
else {
minStep = Math.min(minStep,
solve(map, v, temp, key.node, dst, dp));
}
}
}
v[src] = -1;
dp.put(_key, minStep);
return minStep;
}
// Function to find the minimum number of edge reversals
static int minimumEdgeReversal(int[][] edges,
int n, int src, int dst) {
Map<Integer, List<Pair> > map = new HashMap<>();
for (int[] edge : edges) {
if (map.containsKey(edge[0])) {
// forward edge -> 1
map.get(edge[0]).add(new Pair(edge[1], 1));
}
else {
List<Pair> l = new ArrayList<>();
l.add(new Pair(edge[1], 1));
map.put(edge[0], l);
}
if (map.containsKey(edge[1])) {
// backward edge -> -1
map.get(edge[1]).add(new Pair(edge[0], -1));
}
else {
List<Pair> l = new ArrayList<>();
l.add(new Pair(edge[0], -1));
map.put(edge[1], l);
}
}
// visited
int[] v = new int[n + 1];
Arrays.fill(v, -1);
Map<String, Integer> dp = new HashMap<>();
int step = solve(map, v,
String.valueOf(src), src, dst, dp);
return step == Integer.MAX_VALUE - 1000 ? -1 : step;
}
public static void main(String[] args) {
int[][] edgeList = { {0, 1}, {2, 1}, {2, 3},
{6, 3}, {6, 4}, {4, 5}, {5, 1} };
int n = 7, src = 0, dst = 6;
System.out.println(
minimumEdgeReversal(edgeList, n, src, dst));
}
static class Pair {
public int node;
public int dir;
public Pair(int node, int dir) {
this.node = node;
this.dir = dir;
}
}
}
def solve(mp, v, s, src, dst, dp):
if v[src] == 1:
return 10**9 - 1000
if src == dst:
return 0
_key = s + "-" + str(src)
if _key in dp:
return dp[_key]
v[src] = 1
minStep = 10**9 - 1000
if src in mp:
for key in mp[src]:
temp = s + str(key[0])
if key[1] == -1:
minStep = min(minStep, 1 + solve(mp, v, temp, key[0], dst, dp))
else:
minStep = min(minStep, solve(mp, v, temp, key[0], dst, dp))
v[src] = -1
dp[_key] = minStep
return minStep
def minimumEdgeReversal(edges, n, src, dst):
mp = {}
for edge in edges:
if edge[0] in mp:
mp[edge[0]].append((edge[1], 1))
else:
mp[edge[0]] = [(edge[1], 1)]
if edge[1] in mp:
mp[edge[1]].append((edge[0], -1))
else:
mp[edge[1]] = [(edge[0], -1)]
v = [-1]*(n+1)
dp = {}
step = solve(mp, v, str(src), src, dst, dp)
return -1 if step == 10**9 - 1000 else step
if __name__ == "__main__":
edgeList = [ [0, 1], [2, 1], [2, 3], [6, 3], [6, 4], [4, 5], [5, 1] ]
n = 7; src = 0; dst = 6
print(minimumEdgeReversal(edgeList, n, src, dst))
using System;
using System.Collections.Generic;
class GfG {
// Function to find the minimum cost required
// to run m tasks on n cores is replaced by edge reversal logic
static int solve(Dictionary<int, List<Tuple<int, int>>> map,
int[] v, string s, int src, int dst, Dictionary<string, int> dp) {
if (v[src] == 1)
return int.MaxValue - 1000;
if (src == dst)
return 0;
string _key = s + "-" + src;
if (dp.ContainsKey(_key))
return dp[_key];
v[src] = 1;
int minStep = int.MaxValue - 1000;
if (map.ContainsKey(src)) {
foreach (Tuple<int, int> key in map[src]) {
string temp = s + key.Item1;
if (key.Item2 == -1) {
minStep = Math.Min(minStep, 1 +
solve(map, v, temp, key.Item1, dst, dp));
} else {
minStep = Math.Min(minStep,
solve(map, v, temp, key.Item1, dst, dp));
}
}
}
v[src] = -1;
dp[_key] = minStep;
return minStep;
}
// Function to find the minimum number of edge reversals
static int minimumEdgeReversal(int[][] edges,
int n, int src, int dst) {
Dictionary<int, List<Tuple<int, int>>> map =
new Dictionary<int, List<Tuple<int, int>>>();
foreach (int[] edge in edges) {
if (map.ContainsKey(edge[0])) {
map[edge[0]].Add(new Tuple<int, int>(edge[1], 1));
} else {
List<Tuple<int, int>> l = new List<Tuple<int, int>>();
l.Add(new Tuple<int, int>(edge[1], 1));
map[edge[0]] = l;
}
if (map.ContainsKey(edge[1])) {
map[edge[1]].Add(new Tuple<int, int>(edge[0], -1));
} else {
List<Tuple<int, int>> l = new List<Tuple<int, int>>();
l.Add(new Tuple<int, int>(edge[0], -1));
map[edge[1]] = l;
}
}
int[] v = new int[n + 1];
for (int i = 0; i < n + 1; i++) {
v[i] = -1;
}
Dictionary<string, int> dp = new Dictionary<string, int>();
int step = solve(map, v, src.ToString(), src, dst, dp);
return step == int.MaxValue - 1000 ? -1 : step;
}
static void Main() {
int[][] edgeList = new int[][] {
new int[] {0, 1},
new int[] {2, 1},
new int[] {2, 3},
new int[] {6, 3},
new int[] {6, 4},
new int[] {4, 5},
new int[] {5, 1}
};
int n = 7, src = 0, dst = 6;
Console.WriteLine(minimumEdgeReversal(edgeList, n, src, dst));
}
}
// Function to find the minimum number of edge reversals
function solve(map, v, s, src, dst, dp) {
if (v[src] === 1)
return Number.MAX_SAFE_INTEGER - 1000;
if (src === dst)
return 0;
let _key = s + "-" + src;
if (_key in dp)
return dp[_key];
v[src] = 1;
let minStep = Number.MAX_SAFE_INTEGER - 1000;
if (map[src] !== undefined) {
for (let key of map[src]) {
let temp = s + key[0];
if (key[1] === -1) {
minStep = Math.min(minStep,
1 + solve(map, v, temp, key[0], dst, dp));
} else {
minStep = Math.min(minStep,
solve(map, v, temp, key[0], dst, dp));
}
}
}
v[src] = -1;
dp[_key] = minStep;
return minStep;
}
function minimumEdgeReversal(edges, n, src, dst) {
let map = {};
for (let edge of edges) {
if (map[edge[0]] !== undefined) {
map[edge[0]].push([edge[1], 1]);
} else {
map[edge[0]] = [[edge[1], 1]];
}
if (map[edge[1]] !== undefined) {
map[edge[1]].push([edge[0], -1]);
} else {
map[edge[1]] = [[edge[0], -1]];
}
}
let v = new Array(n + 1).fill(-1);
let dp = {};
let step = solve(map, v, String(src), src, dst, dp);
return step === Number.MAX_SAFE_INTEGER - 1000 ? -1 : step;
}
let edgeList = [ [0, 1], [2, 1], [2, 3], [6, 3], [6, 4], [4, 5], [5, 1] ];
let n = 7, src = 0, dst = 6;
console.log(minimumEdgeReversal(edgeList, n, src, dst));
Output
2
[Expected Approach] - By Creating Reverse Edges - O(m * log(n)) Time and O(n + m) Space
The idea here is to make the graph undirected by adding all edges in the reverse direction. Assign weight zero to all edges that are not reversed and weight 1 to all edges that are reversed. Then, use the Dijkstra algorithm to find the minimum weight path from the starting node to the ending node to get the minimum number of operations.
After adding the reversed edges in the graph, it will look like this:
Below is given the implementation:
#include <bits/stdc++.h>
using namespace std;
// Function to find the minimum number of edge reversals
int minimumEdgeReversal(vector<vector<int>> &edges,
int n, int src, int dst) {
// Creating adjacency list for the given graph
vector<vector<pair<int, int>>> g(n + 2);
// Adding edges to the adjacency list
for (auto it : edges) {
g[it[0]].push_back({it[1], 0});
g[it[1]].push_back({it[0], 1});
}
// Using Dijkstra's algorithm to find the shortest path
// from src to dst with minimum edge reversals
// Creating a priority queue to store
// the vertices with their distances
priority_queue<pair<int, int>, vector<pair<int, int>>,
greater<pair<int, int>>> pq;
// Creating a vector to store the
// distances of all vertices from src
vector<int> dis(n + 1, INT_MAX);
// Setting the distance of the source vertex to 0
dis[src] = 0;
// Inserting the source vertex into the priority queue
pq.push({0, src});
// Performing Dijkstra's algorithm
while (!pq.empty()) {
// Getting the vertex with the minimum distance
pair<int, int> p = pq.top();
pq.pop();
int u = p.second;
int w1 = p.first;
// Iterating over the neighbors of the current vertex
for (pair<int, int> nxt : g[u]) {
int v = nxt.first;
int w2 = nxt.second;
// Updating the distance of the neighbor
// if a shorter path is found
if (w1 + w2 < dis[v]) {
dis[v] = w1 + w2;
// Inserting the neighbor
// into the priority queue
pq.push({dis[v], v});
}
}
}
// If the distance to the destination vertex is still INT_MAX,
// this means that there is no path from src to dst
if (dis[dst] == INT_MAX)
return -1;
// Returning the distance of
// the destination vertex from src
return dis[dst];
}
int main() {
vector<vector<int>> edges = { {0, 1}, {2, 1}, {2, 3}, {6, 3}, {6, 4}, {4, 5}, {5, 1} };
int n = 7, src = 0, dst = 6;
cout << minimumEdgeReversal(edges, n, src, dst);
return 0;
}
// Function to find the minimum cost required
// to run m tasks on n cores
import java.util.*;
class GfG {
// Function to find the minimum number of edge reversals
static int minimumEdgeReversal(int[][] edges,
int n, int src, int dst) {
// Creating adjacency list for the given graph
ArrayList<ArrayList<Pair>> g = new ArrayList<>();
for (int i = 0; i < n + 2; i++) {
g.add(new ArrayList<>());
}
for (int i = 0; i < edges.length; i++) {
g.get(edges[i][0]).add(new Pair(edges[i][1], 0));
g.get(edges[i][1]).add(new Pair(edges[i][0], 1));
}
// Creating a priority queue to store
// the vertices with their distances
PriorityQueue<PairInt> pq = new
PriorityQueue<>(new Comparator<PairInt>() {
public int compare(PairInt a, PairInt b) {
return Integer.compare(a.first, b.first);
}
});
// Creating a vector to store the
// distances of all vertices from src
int[] dis = new int[n + 1];
Arrays.fill(dis, Integer.MAX_VALUE);
// Setting the distance of the source vertex to 0
dis[src] = 0;
// Inserting the source vertex into the priority queue
pq.add(new PairInt(0, src));
// Performing Dijkstra's algorithm
while (!pq.isEmpty()) {
PairInt p = pq.poll();
int u = p.second;
int w1 = p.first;
// Iterating over the neighbors of the current vertex
for (Pair nxt : g.get(u)) {
int v = nxt.first;
int w2 = nxt.second;
// Updating the distance of the neighbor
// if a shorter path is found
if (w1 + w2 < dis[v]) {
dis[v] = w1 + w2;
// Inserting the neighbor
// into the priority queue
pq.add(new PairInt(dis[v], v));
}
}
}
// If the distance to the destination
// vertex is still Integer.MAX_VALUE,
// this means that there is no path from src to dst
if (dis[dst] == Integer.MAX_VALUE)
return -1;
// Returning the distance of
// the destination vertex from src
return dis[dst];
}
public static void main(String[] args) {
int[][] edgeList = { {0, 1}, {2, 1}, {2, 3}, {6, 3}, {6, 4}, {4, 5}, {5, 1} };
int n = 7, src = 0, dst = 6;
System.out.println(minimumEdgeReversal(edgeList, n, src, dst));
}
}
class Pair {
int first, second;
Pair(int first, int second) {
this.first = first;
this.second = second;
}
}
class PairInt {
int first, second;
PairInt(int first, int second) {
this.first = first;
this.second = second;
}
}
# Function to find the minimum number of edge reversals
def minimumEdgeReversal(edges, n, src, dst):
# Creating adjacency list for the given graph
g = [[] for _ in range(n + 2)]
for edge in edges:
g[edge[0]].append((edge[1], 0))
g[edge[1]].append((edge[0], 1))
# Creating a priority queue to store
# the vertices with their distances
import heapq
pq = []
# Creating a vector to store the
# distances of all vertices from src
dis = [float('inf')] * (n + 1)
# Setting the distance of the source vertex to 0
dis[src] = 0
# Inserting the source vertex into the priority queue
heapq.heappush(pq, (0, src))
# Performing Dijkstra's algorithm
while pq:
w1, u = heapq.heappop(pq)
# Iterating over the neighbors of the current vertex
for (v, w2) in g[u]:
# Updating the distance of the neighbor
# if a shorter path is found
if w1 + w2 < dis[v]:
dis[v] = w1 + w2
# Inserting the neighbor
# into the priority queue
heapq.heappush(pq, (dis[v], v))
# If the distance to the destination vertex is still infinity,
# this means that there is no path from src to dst
if dis[dst] == float('inf'):
return -1
# Returning the distance of
# the destination vertex from src
return dis[dst]
if __name__ == "__main__":
edgeList = [ [0, 1], [2, 1], [2, 3], [6, 3], [6, 4], [4, 5], [5, 1] ]
n = 7
src = 0
dst = 6
print(minimumEdgeReversal(edgeList, n, src, dst))
// Function to find the minimum number of edge reversals
using System;
using System.Collections.Generic;
class GfG {
// Function to find the minimum number of edge reversals
static int minimumEdgeReversal(List<List<int>> edges,
int n, int src, int dst) {
// Creating adjacency list for the given graph
List<List<Tuple<int, int>>> g =
new List<List<Tuple<int, int>>>();
for (int i = 0; i < n + 2; i++) {
g.Add(new List<Tuple<int, int>>());
}
for (int i = 0; i < edges.Count; i++) {
int u = edges[i][0];
int v = edges[i][1];
g[u].Add(new Tuple<int, int>(v, 0));
g[v].Add(new Tuple<int, int>(u, 1));
}
// Creating a priority queue to store
// the vertices with their distances
SortedSet<Tuple<int, int>> pq =
new SortedSet<Tuple<int, int>>
(Comparer<Tuple<int, int>>.Create((a, b) =>
{
int cmp = a.Item1.CompareTo(b.Item1);
return cmp == 0 ? a.Item2.CompareTo(b.Item2) : cmp;
}));
// Creating a vector to store the
// distances of all vertices from src
int[] dis = new int[n + 1];
for (int i = 0; i < n + 1; i++) {
dis[i] = int.MaxValue;
}
// Setting the distance of the source vertex to 0
dis[src] = 0;
// Inserting the source vertex into the priority queue
pq.Add(new Tuple<int, int>(0, src));
// Performing Dijkstra's algorithm
while (pq.Count > 0) {
Tuple<int, int> p = pq.Min;
pq.Remove(p);
int u = p.Item2;
int w1 = p.Item1;
// Iterating over the neighbors of the current vertex
foreach (Tuple<int, int> nxt in g[u]) {
int v = nxt.Item1;
int w2 = nxt.Item2;
// Updating the distance of the neighbor
// if a shorter path is found
if (w1 + w2 < dis[v]) {
dis[v] = w1 + w2;
// Inserting the neighbor
// into the priority queue
pq.Add(new Tuple<int, int>(dis[v], v));
}
}
}
// If the distance to the destination
// vertex is still int.MaxValue,
// this means that there is no path from src to dst
if (dis[dst] == int.MaxValue)
return -1;
// Returning the distance of
// the destination vertex from src
return dis[dst];
}
static void Main() {
List<List<int>> edgeList = new List<List<int>> {
new List<int> {0, 1},
new List<int> {2, 1},
new List<int> {2, 3},
new List<int> {6, 3},
new List<int> {6, 4},
new List<int> {4, 5},
new List<int> {5, 1}
};
int n = 7, src = 0, dst = 6;
Console.WriteLine(minimumEdgeReversal(edgeList, n, src, dst));
}
}
// Function to find the minimum number of edge reversals
// required to run m tasks on n cores.
function minimumEdgeReversal(edges, n, src, dst) {
// Creating adjacency list for the given graph
let g = new Array(n + 2);
for (let i = 0; i < n + 2; i++) {
g[i] = [];
}
for (let i = 0; i < edges.length; i++) {
g[edges[i][0]].push([edges[i][1], 0]);
g[edges[i][1]].push([edges[i][0], 1]);
}
// Creating a priority queue to store
// the vertices with their distances (simulated)
class MinHeap {
constructor() {
this.heap = [];
}
push(item) {
this.heap.push(item);
this.bubbleUp(this.heap.length - 1);
}
pop() {
if (this.heap.length === 0) return null;
const top = this.heap[0];
const end = this.heap.pop();
if (this.heap.length > 0) {
this.heap[0] = end;
this.bubbleDown(0);
}
return top;
}
bubbleUp(index) {
while (index > 0) {
let parent = Math.floor((index - 1) / 2);
if (this.heap[index][0] < this.heap[parent][0]) {
[this.heap[index], this.heap[parent]] =
[this.heap[parent], this.heap[index]];
index = parent;
} else {
break;
}
}
}
bubbleDown(index) {
let length = this.heap.length;
while (true) {
let left = 2 * index + 1;
let right = 2 * index + 2;
let smallest = index;
if (left < length && this.heap[left][0] <
this.heap[smallest][0])
smallest = left;
if (right < length && this.heap[right][0] <
this.heap[smallest][0])
smallest = right;
if (smallest !== index) {
[this.heap[index], this.heap[smallest]] =
[this.heap[smallest], this.heap[index]];
index = smallest;
} else {
break;
}
}
}
size() {
return this.heap.length;
}
}
let pq = new MinHeap();
// Creating a vector to store the
// distances of all vertices from src
let dis = new Array(n + 1).fill(Infinity);
// Setting the distance of the source vertex to 0
dis[src] = 0;
// Inserting the source vertex into the priority queue
pq.push([0, src]);
// Performing Dijkstra's algorithm
while (pq.size() > 0) {
let p = pq.pop();
let u = p[1];
let w1 = p[0];
// Iterating over the neighbors of the current vertex
for (let i = 0; i < g[u].length; i++) {
let v = g[u][i][0];
let w2 = g[u][i][1];
// Updating the distance of the neighbor
// if a shorter path is found
if (w1 + w2 < dis[v]) {
dis[v] = w1 + w2;
// Inserting the neighbor
// into the priority queue
pq.push([dis[v], v]);
}
}
}
// If the distance to the destination vertex is still Infinity,
// this means that there is no path from src to dst
if (dis[dst] === Infinity)
return -1;
// Returning the distance of
// the destination vertex from src
return dis[dst];
}
let edges = [ [0, 1], [2, 1], [2, 3], [6, 3], [6, 4], [4, 5], [5, 1] ];
let n = 7, src = 0, dst = 6;
console.log(minimumEdgeReversal(edges, n, src, dst));
Output
2
[Optimal Approach] - Using Deque - O(n + m) Time and O(n + m) Space
Instead of a priority queue we can use a dequeue which inserts edges with weight 0 from front and edges with weight 1 (reversed edges) from back so that it is filled in the dequeue in sorted manner.
Follow the below given steps:
- Graph Construction:
- Create an adjacency list from the given directed edges.
- For each edge
(from → to)
, add:- A forward edge
(to, 0)
(no reversal needed). - A backward edge
(from, 1)
(reversal required).
- A forward edge
- Initialization:
- Create a
dist
vector, setting all distances toINT_MAX
. - Initialize a deque
dq
for a modified BFS. - Set
dist[src] = 0
and addsrc
todq
.
- Create a
- Modified BFS Traversal:
- While
dq
is not empty:- Dequeue a node
node
. - Iterate through its neighbors
(node2, weight)
. - If
dist[node] + weight < dist[node2]
:- Update
dist[node2]
. - Push
node2
to the front (weight 0
) or back (weight 1
) ofdq
.
- Update
- Dequeue a node
- While
- Result Evaluation:
- If
dist[dst] == INT_MAX
, return-1
(no valid path). - Otherwise, return
dist[dst]
, the minimum edge reversals required.
- If
Below is given the implementation:
#include <bits/stdc++.h>
using namespace std;
// Function to find the minimum number of edge reversals
int minimumEdgeReversal(vector<vector<int>> &edges,
int n, int src, int dst) {
// Creating adjacency list for the given graph
vector<vector<pair<int, int>>> adj(n + 1);
int m = edges.size();
for (int i = 0; i < m; i++) {
int from = edges[i][0];
int to = edges[i][1];
adj[from].push_back({to, 0});
adj[to].push_back({from, 1});
}
// Using BFS to find the shortest path
vector<int> dist(n + 1, INT_MAX);
// Creating a deque to store the vertices
deque<int> dq;
dq.push_back(src);
dist[src] = 0;
// Performing BFS
while (dq.size() > 0) {
int node = dq.front();
dq.pop_front();
// Iterating over the neighbors of the current vertex
for (int i = 0; i < adj[node].size(); i++) {
int node2 = adj[node][i].first;
int weight = adj[node][i].second;
// Updating the distance of the neighbor
// if a shorter path is found
if (dist[node] + weight < dist[node2]) {
dist[node2] = dist[node] + weight;
// Inserting the neighbor into the deque
if (weight == 0)
dq.push_front(node2);
else
dq.push_back(node2);
}
}
}
// If the distance of the destination vertex is INT_MAX
// then there is no path from src to dst
if (dist[dst] == INT_MAX)
return -1;
return dist[dst];
}
int main() {
vector<vector<int>> edges = {{0, 1}, {2, 1},
{2, 3}, {6, 3}, {6, 4}, {4, 5}, {5, 1}};
int n = 7, src = 0, dst = 6;
cout << minimumEdgeReversal(edges, n, src, dst);
return 0;
}
import java.util.*;
class GfG {
// Function to find the minimum number of edge reversals
static int minimumEdgeReversal(int[][] edges,
int n, int src, int dst) {
// Creating adjacency list for the given graph
List<List<int[]>> adj = new ArrayList<>();
for (int i = 0; i <= n; i++)
adj.add(new ArrayList<>());
int m = edges.length;
for (int i = 0; i < m; i++) {
int fromNode = edges[i][0];
int toNode = edges[i][1];
adj.get(fromNode).add(new int[]{toNode, 0});
adj.get(toNode).add(new int[]{fromNode, 1});
}
// Using BFS to find the shortest path
int[] dist = new int[n + 1];
Arrays.fill(dist, Integer.MAX_VALUE);
// Creating a deque to store the vertices
Deque<Integer> dq = new ArrayDeque<>();
dq.addLast(src);
dist[src] = 0;
// Performing BFS
while (!dq.isEmpty()) {
int node = dq.pollFirst();
// Iterating over the neighbors of the current vertex
for (int[] neighbor : adj.get(node)) {
int node2 = neighbor[0];
int weight = neighbor[1];
// Updating the distance of the neighbor
// if a shorter path is found
if (dist[node] + weight < dist[node2]) {
dist[node2] = dist[node] + weight;
// Inserting the neighbor into the deque
if (weight == 0)
dq.addFirst(node2);
else
dq.addLast(node2);
}
}
}
// If the distance of the destination vertex is Integer.MAX_VALUE
// then there is no path from src to dst
if (dist[dst] == Integer.MAX_VALUE)
return -1;
return dist[dst];
}
public static void main(String[] args) {
int[][] edges = {{0, 1}, {2, 1}, {2, 3}, {6, 3},
{6, 4}, {4, 5}, {5, 1}};
int n = 7, src = 0, dst = 6;
System.out.println(minimumEdgeReversal(edges, n, src, dst));
}
}
from collections import deque
# Function to find the minimum number of edge reversals
def minimumEdgeReversal(edges, n, src, dst):
# Creating adjacency list for the given graph
adj = [[] for _ in range(n + 1)]
m = len(edges)
for i in range(m):
fromNode = edges[i][0]
toNode = edges[i][1]
adj[fromNode].append((toNode, 0))
adj[toNode].append((fromNode, 1))
# Using BFS to find the shortest path
dist = [float('inf')] * (n + 1)
# Creating a deque to store the vertices
dq = deque()
dq.append(src)
dist[src] = 0
# Performing BFS
while len(dq) > 0:
node = dq.popleft()
# Iterating over the neighbors of the current vertex
for i in range(len(adj[node])):
node2, weight = adj[node][i]
# Updating the distance of the neighbor
# if a shorter path is found
if dist[node] + weight < dist[node2]:
dist[node2] = dist[node] + weight
# Inserting the neighbor into the deque
if weight == 0:
dq.appendleft(node2)
else:
dq.append(node2)
# If the distance of the destination vertex is float('inf')
# then there is no path from src to dst
if dist[dst] == float('inf'):
return -1
return dist[dst]
if __name__ == "__main__":
edges = [[0, 1], [2, 1], [2, 3], [6, 3], [6, 4], [4, 5], [5, 1]]
n = 7
src = 0
dst = 6
print(minimumEdgeReversal(edges, n, src, dst))
using System;
using System.Collections.Generic;
class GfG {
// Function to find the minimum number of edge reversals
static int minimumEdgeReversal(List<List<int>> edges,
int n, int src, int dst) {
// Creating adjacency list for the given graph
List<List<Tuple<int, int>>> adj =
new List<List<Tuple<int, int>>>();
for (int i = 0; i <= n; i++)
adj.Add(new List<Tuple<int, int>>());
int m = edges.Count;
for (int i = 0; i < m; i++) {
int fromNode = edges[i][0];
int toNode = edges[i][1];
adj[fromNode].Add(new Tuple<int, int>(toNode, 0));
adj[toNode].Add(new Tuple<int, int>(fromNode, 1));
}
// Using BFS to find the shortest path
int[] dist = new int[n + 1];
for (int i = 0; i <= n; i++)
dist[i] = int.MaxValue;
// Creating a deque to store the vertices
LinkedList<int> dq = new LinkedList<int>();
dq.AddLast(src);
dist[src] = 0;
// Performing BFS
while (dq.Count > 0) {
int node = dq.First.Value;
dq.RemoveFirst();
// Iterating over the neighbors of the current vertex
for (int i = 0; i < adj[node].Count; i++) {
int node2 = adj[node][i].Item1;
int weight = adj[node][i].Item2;
// Updating the distance of the neighbor
// if a shorter path is found
if (dist[node] + weight < dist[node2]) {
dist[node2] = dist[node] + weight;
// Inserting the neighbor into the deque
if (weight == 0)
dq.AddFirst(node2);
else
dq.AddLast(node2);
}
}
}
// If the distance of the destination vertex is int.MaxValue
// then there is no path from src to dst
if (dist[dst] == int.MaxValue)
return -1;
return dist[dst];
}
static void Main() {
List<List<int>> edges = new List<List<int>> {
new List<int> {0, 1},
new List<int> {2, 1},
new List<int> {2, 3},
new List<int> {6, 3},
new List<int> {6, 4},
new List<int> {4, 5},
new List<int> {5, 1}
};
int n = 7, src = 0, dst = 6;
Console.WriteLine(minimumEdgeReversal(edges, n, src, dst));
}
}
// Function to find the minimum number of edge reversals
function minimumEdgeReversal(edges, n, src, dst) {
// Creating adjacency list for the given graph
let adj = new Array(n + 1).fill(null).map(() => []);
let m = edges.length;
for (let i = 0; i < m; i++) {
let fromNode = edges[i][0];
let toNode = edges[i][1];
adj[fromNode].push([toNode, 0]);
adj[toNode].push([fromNode, 1]);
}
// Using BFS to find the shortest path
let dist = new Array(n + 1).fill(Number.MAX_SAFE_INTEGER);
// Creating a deque to store the vertices
let dq = [];
dq.push(src);
dist[src] = 0;
// Performing BFS
while (dq.length > 0) {
let node = dq.shift();
// Iterating over the neighbors of the current vertex
for (let i = 0; i < adj[node].length; i++) {
let node2 = adj[node][i][0];
let weight = adj[node][i][1];
// Updating the distance of the neighbor
// if a shorter path is found
if (dist[node] + weight < dist[node2]) {
dist[node2] = dist[node] + weight;
// Inserting the neighbor into the deque
if (weight === 0)
dq.unshift(node2);
else
dq.push(node2);
}
}
}
// If the distance of the destination
// vertex is Number.MAX_SAFE_INTEGER
// then there is no path from src to dst
if (dist[dst] === Number.MAX_SAFE_INTEGER)
return -1;
return dist[dst];
}
let edges = [[0, 1], [2, 1], [2, 3],
[6, 3], [6, 4], [4, 5], [5, 1]];
let n = 7, src = 0, dst = 6;
console.log(minimumEdgeReversal(edges, n, src, dst));
Output
2