Minimum edges to reverse to make path from a source to a destination
Last Updated : 21 Aug, 2026
Given a directed graph with n vertices numbered from 1 to n and m directed edges. The graph is represented using a 2D array edges[][] of size m, where each entry edges[i] = [u, v] denotes a directed edge from vertex u to vertex v.
A source vertex src and a destination vertex dst are also given.
Find the minimum number of edges that need to be reversed so that there exists at least one path from src to dst.
If it is not possible to create a path from src to dst, return -1.
[Naive Approach] DFS with Backtracking - Exponential Time and O(n + m) Space
The idea is to try all possible paths from src to dst and find the path that requires the minimum number of edge reversals.
To do this, first convert the given directed graph into a weighted graph.
For every directed edge u -> v, add two edges:
u -> v with cost 0, because we can use the edge in its original direction without reversing it.
v -> u with cost 1, because using the edge in the opposite direction requires reversing it.
Then perform DFS from src. For every path that reaches dst, calculate its total cost and keep the minimum.
A visited array is used to avoid cycles. After exploring a node, it is unmarked so that it can be used in other possible paths.
C++
#include<bits/stdc++.h>usingnamespacestd;// Recursive function to find the minimum edge reversals.intsolve(vector<vector<pair<int,int>>>&adj,vector<bool>&vis,intsrc,intdst){// Destination is reached.if(src==dst)return0;vis[src]=true;intans=INT_MAX;// Explore all possible paths.for(auto&edge:adj[src]){intnode=edge.first;intcost=edge.second;if(!vis[node]){intres=solve(adj,vis,node,dst);if(res!=INT_MAX)ans=min(ans,cost+res);}}// Backtrack to explore other paths.vis[src]=false;returnans;}// Function to find the minimum number of edge reversals.intminimumEdgeReversal(vector<vector<int>>&edges,intn,intsrc,intdst){vector<vector<pair<int,int>>>adj(n+1);// Create adjacency list with both directions.for(auto&edge:edges){intu=edge[0];intv=edge[1];// Original direction requires no reversal.adj[u].push_back({v,0});// Reverse direction requires one reversal.adj[v].push_back({u,1});}vector<bool>vis(n+1,false);intans=solve(adj,vis,src,dst);// No path exists from src to dst.if(ans==INT_MAX)return-1;returnans;}intmain(){intn=3;vector<vector<int>>edges={{1,2},{3,2}};intsrc=1;intdst=3;cout<<minimumEdgeReversal(edges,n,src,dst);return0;}
Java
importjava.util.ArrayList;classGFG{// Recursive function to find the minimum edge reversals.staticintsolve(ArrayList<ArrayList<int[]>>adj,boolean[]vis,intsrc,intdst){// Destination is reached.if(src==dst)return0;vis[src]=true;intans=Integer.MAX_VALUE;// Explore all possible paths.for(int[]edge:adj.get(src)){intnode=edge[0];intcost=edge[1];if(!vis[node]){intres=solve(adj,vis,node,dst);if(res!=Integer.MAX_VALUE)ans=Math.min(ans,cost+res);}}// Backtrack to explore other paths.vis[src]=false;returnans;}// Function to find the minimum number of edge reversals.staticintminimumEdgeReversal(int[][]edges,intn,intsrc,intdst){ArrayList<ArrayList<int[]>>adj=newArrayList<>();for(inti=0;i<=n;i++)adj.add(newArrayList<>());// Create adjacency list with both directions.for(int[]edge:edges){intu=edge[0];intv=edge[1];// Original direction requires no reversal.adj.get(u).add(newint[]{v,0});// Reverse direction requires one reversal.adj.get(v).add(newint[]{u,1});}boolean[]vis=newboolean[n+1];intans=solve(adj,vis,src,dst);// No path exists from src to dst.if(ans==Integer.MAX_VALUE)return-1;returnans;}publicstaticvoidmain(String[]args){intn=3;int[][]edges={{1,2},{3,2}};intsrc=1;intdst=3;System.out.println(minimumEdgeReversal(edges,n,src,dst));}}
Python
# Recursive function to find the minimum edge reversals.defsolve(adj,vis,src,dst):# Destination is reached.ifsrc==dst:return0vis[src]=Trueans=float('inf')# Explore all possible paths.foredgeinadj[src]:node=edge[0]cost=edge[1]ifnotvis[node]:res=solve(adj,vis,node,dst)ifres!=float('inf'):ans=min(ans,cost+res)# Backtrack to explore other paths.vis[src]=Falsereturnans# Function to find the minimum number of edge reversals.defminimumEdgeReversal(edges,n,src,dst):adj=[[]for_inrange(n+1)]# Create adjacency list with both directions.foredgeinedges:u=edge[0]v=edge[1]# Original direction requires no reversal.adj[u].append([v,0])# Reverse direction requires one reversal.adj[v].append([u,1])vis=[False]*(n+1)ans=solve(adj,vis,src,dst)# No path exists from src to dst.ifans==float('inf'):return-1returnansif__name__=="__main__":n=3edges=[[1,2],[3,2]]src=1dst=3print(minimumEdgeReversal(edges,n,src,dst))
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Recursive function to find the minimum edge reversals.staticintsolve(List<List<int[]>>adj,bool[]vis,intsrc,intdst){// Destination is reached.if(src==dst)return0;vis[src]=true;intans=int.MaxValue;// Explore all possible paths.foreach(int[]edgeinadj[src]){intnode=edge[0];intcost=edge[1];if(!vis[node]){intres=solve(adj,vis,node,dst);if(res!=int.MaxValue)ans=Math.Min(ans,cost+res);}}// Backtrack to explore other paths.vis[src]=false;returnans;}// Function to find the minimum number of edge reversals.staticintminimumEdgeReversal(int[][]edges,intn,intsrc,intdst){List<List<int[]>>adj=newList<List<int[]>>();for(inti=0;i<=n;i++)adj.Add(newList<int[]>());// Create adjacency list with both directions.foreach(int[]edgeinedges){intu=edge[0];intv=edge[1];// Original direction requires no reversal.adj[u].Add(newint[]{v,0});// Reverse direction requires one reversal.adj[v].Add(newint[]{u,1});}bool[]vis=newbool[n+1];intans=solve(adj,vis,src,dst);// No path exists from src to dst.if(ans==int.MaxValue)return-1;returnans;}publicstaticvoidMain(){intn=3;int[][]edges={newint[]{1,2},newint[]{3,2}};intsrc=1;intdst=3;Console.WriteLine(minimumEdgeReversal(edges,n,src,dst));}}
JavaScript
// Recursive function to find the minimum edge reversals.functionsolve(adj,vis,src,dst){// Destination is reached.if(src===dst)return0;vis[src]=true;letans=Infinity;// Explore all possible paths.for(letedgeofadj[src]){letnode=edge[0];letcost=edge[1];if(!vis[node]){letres=solve(adj,vis,node,dst);if(res!==Infinity)ans=Math.min(ans,cost+res);}}// Backtrack to explore other paths.vis[src]=false;returnans;}// Function to find the minimum number of edge reversals.functionminimumEdgeReversal(edges,n,src,dst){letadj=Array.from({length:n+1},()=>[]);// Create adjacency list with both directions.for(letedgeofedges){letu=edge[0];letv=edge[1];// Original direction requires no reversal.adj[u].push([v,0]);// Reverse direction requires one reversal.adj[v].push([u,1]);}letvis=newArray(n+1).fill(false);letans=solve(adj,vis,src,dst);// No path exists from src to dst.if(ans===Infinity)return-1;returnans;}// Driver codeletn=3;letedges=[[1,2],[3,2]];letsrc=1;letdst=3;console.log(minimumEdgeReversal(edges,n,src,dst));
Output
1
[Better Approach] By Creating Reverse Edges - O((n + m)*log(n)) Time and O(n + m) Space
The idea is to convert the given graph into a weighted graph and run Dijkstra's Algorithm
For every directed edge u -> v, add:
u -> v with cost 0, since it is already in the required direction.
v -> u with cost 1, since using it in this direction requires a reversal.
Thus, the cost of a path from src to dst equals the number of edge reversals required. So, we need to find the minimum-cost path.
Once the graph is converted into a weighted graph, we can use Dijkstra's Algorithm to find the minimum-cost path.
Maintain a dist[] array where: dist[i] = minimum number of reversals required to reach vertex i from src.
Initially, set the distance of every vertex to infinity and set: dist[src] = 0
Then use a priority queue to always process the vertex with the smallest current distance.
For every edge (node, next, cost), calculate: newDist = dist[node] + cost
If newDist is smaller than dist[next], update dist[next] and add it to the priority queue.
Finally: If dist[dst] is infinity, return -1.
Otherwise, dist[dst] is the minimum number of edges that need to be reversed.
C++
#include<bits/stdc++.h>usingnamespacestd;// Function to find the minimum number of edge reversals.intminimumEdgeReversal(vector<vector<int>>&edges,intn,intsrc,intdst){vector<vector<pair<int,int>>>adj(n+1);// Create adjacency list with both directions.for(auto&edge:edges){intu=edge[0];intv=edge[1];// Original direction requires no reversal.adj[u].push_back({v,0});// Reverse direction requires one reversal.adj[v].push_back({u,1});}// Store the minimum reversals required to reach each node.vector<int>dist(n+1,INT_MAX);// Priority queue stores {distance, node}.priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>pq;// Distance of source is 0.dist[src]=0;pq.push({0,src});// Apply Dijkstra's algorithm.while(!pq.empty()){auto[d,node]=pq.top();pq.pop();// Skip outdated entries.if(d!=dist[node])continue;// Explore all adjacent nodes.for(auto&edge:adj[node]){intnext=edge.first;intcost=edge.second;// Update the distance if a better path is found.if(d+cost<dist[next]){dist[next]=d+cost;pq.push({dist[next],next});}}}// No path exists from src to dst.if(dist[dst]==INT_MAX)return-1;returndist[dst];}intmain(){intn=3;vector<vector<int>>edges={{1,2},{3,2}};intsrc=1;intdst=3;cout<<minimumEdgeReversal(edges,n,src,dst);return0;}
Java
importjava.util.*;classGFG{// Function to find the minimum number of edge reversals.publicstaticintminimumEdgeReversal(int[][]edges,intn,intsrc,intdst){ArrayList<ArrayList<int[]>>adj=newArrayList<>();for(inti=0;i<=n;i++)adj.add(newArrayList<>());// Create adjacency list with both directions.for(int[]edge:edges){intu=edge[0];intv=edge[1];// Original direction requires no reversal.adj.get(u).add(newint[]{v,0});// Reverse direction requires one reversal.adj.get(v).add(newint[]{u,1});}// Store the minimum reversals required to reach each node.int[]dist=newint[n+1];Arrays.fill(dist,Integer.MAX_VALUE);// Priority queue stores {distance, node}.PriorityQueue<int[]>pq=newPriorityQueue<>((a,b)->Integer.compare(a[0],b[0]));// Distance of source is 0.dist[src]=0;pq.offer(newint[]{0,src});// Apply Dijkstra's algorithm.while(!pq.isEmpty()){int[]cur=pq.poll();intd=cur[0];intnode=cur[1];// Skip outdated entries.if(d!=dist[node])continue;// Explore all adjacent nodes.for(int[]edge:adj.get(node)){intnext=edge[0];intcost=edge[1];// Update the distance if a better path is found.if(d+cost<dist[next]){dist[next]=d+cost;pq.offer(newint[]{dist[next],next});}}}// No path exists from src to dst.if(dist[dst]==Integer.MAX_VALUE)return-1;returndist[dst];}publicstaticvoidmain(String[]args){intn=3;int[][]edges={{1,2},{3,2}};intsrc=1;intdst=3;System.out.println(minimumEdgeReversal(edges,n,src,dst));}}
Python
importheapq# Function to find the minimum number of edge reversals.defminimumEdgeReversal(edges,n,src,dst):adj=[[]for_inrange(n+1)]# Create adjacency list with both directions.foredgeinedges:u=edge[0]v=edge[1]# Original direction requires no reversal.adj[u].append([v,0])# Reverse direction requires one reversal.adj[v].append([u,1])# Store the minimum reversals required to reach each node.dist=[float('inf')]*(n+1)# Priority queue stores {distance, node}.pq=[]# Distance of source is 0.dist[src]=0heapq.heappush(pq,(0,src))# Apply Dijkstra's algorithm.whilepq:d,node=heapq.heappop(pq)# Skip outdated entries.ifd!=dist[node]:continue# Explore all adjacent nodes.foredgeinadj[node]:next=edge[0]cost=edge[1]# Update the distance if a better path is found.ifd+cost<dist[next]:dist[next]=d+costheapq.heappush(pq,(dist[next],next))# No path exists from src to dst.ifdist[dst]==float('inf'):return-1returndist[dst]if__name__=="__main__":n=3edges=[[1,2],[3,2]]src=1dst=3print(minimumEdgeReversal(edges,n,src,dst))
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Function to find the minimum number of edge reversals.publicstaticintminimumEdgeReversal(int[][]edges,intn,intsrc,intdst){List<List<int[]>>adj=newList<List<int[]>>();for(inti=0;i<=n;i++)adj.Add(newList<int[]>());// Create adjacency list with both directions.foreach(int[]edgeinedges){intu=edge[0];intv=edge[1];// Original direction requires no reversal.adj[u].Add(newint[]{v,0});// Reverse direction requires one reversal.adj[v].Add(newint[]{u,1});}// Store the minimum reversals required to reach each node.int[]dist=newint[n+1];Array.Fill(dist,int.MaxValue);// Priority queue stores {distance, node}.PriorityQueue<int[],int>pq=newPriorityQueue<int[],int>();// Distance of source is 0.dist[src]=0;pq.Enqueue(newint[]{0,src},0);// Apply Dijkstra's algorithm.while(pq.Count>0){int[]cur=pq.Dequeue();intd=cur[0];intnode=cur[1];// Skip outdated entries.if(d!=dist[node])continue;// Explore all adjacent nodes.foreach(int[]edgeinadj[node]){intnext=edge[0];intcost=edge[1];// Update the distance if a better path is found.if(d+cost<dist[next]){dist[next]=d+cost;pq.Enqueue(newint[]{dist[next],next},dist[next]);}}}// No path exists from src to dst.if(dist[dst]==int.MaxValue)return-1;returndist[dst];}publicstaticvoidMain(){intn=3;int[][]edges={newint[]{1,2},newint[]{3,2}};intsrc=1;intdst=3;Console.WriteLine(minimumEdgeReversal(edges,n,src,dst));}}
JavaScript
// Function to find the minimum number of edge reversals.functionminimumEdgeReversal(edges,n,src,dst){letadj=Array.from({length:n+1},()=>[]);// Create adjacency list with both directions.for(letedgeofedges){letu=edge[0];letv=edge[1];// Original direction requires no reversal.adj[u].push([v,0]);// Reverse direction requires one reversal.adj[v].push([u,1]);}// Store the minimum reversals required to reach each// node.letdist=newArray(n+1).fill(Infinity);// Priority queue stores {distance, node}.letpq=[];functionpush(item){pq.push(item);leti=pq.length-1;while(i>0){letparent=Math.floor((i-1)/2);if(pq[parent][0]<=pq[i][0])break;[pq[parent],pq[i]]=[pq[i],pq[parent]];i=parent;}}functionpop(){lettop=pq[0];letlast=pq.pop();if(pq.length>0){pq[0]=last;leti=0;while(true){letleft=2*i+1;letright=2*i+2;letsmallest=i;if(left<pq.length&&pq[left][0]<pq[smallest][0])smallest=left;if(right<pq.length&&pq[right][0]<pq[smallest][0])smallest=right;if(smallest===i)break;[pq[i],pq[smallest]]=[pq[smallest],pq[i]];i=smallest;}}returntop;}// Distance of source is 0.dist[src]=0;push([0,src]);// Apply Dijkstra's algorithm.while(pq.length>0){letcur=pop();letd=cur[0];letnode=cur[1];// Skip outdated entries.if(d!==dist[node])continue;// Explore all adjacent nodes.for(letedgeofadj[node]){letnext=edge[0];letcost=edge[1];// Update the distance if a better path is// found.if(d+cost<dist[next]){dist[next]=d+cost;push([dist[next],next]);}}}// No path exists from src to dst.if(dist[dst]===Infinity)return-1;returndist[dst];}// Driver codeletn=3;letedges=[[1,2],[3,2]];letsrc=1;letdst=3;console.log(minimumEdgeReversal(edges,n,src,dst));
Output
1
[Expected Approach] Using 0-1 BFS - O(n + m) Time and O(n + m) Space
Since every edge in the transformed graph has a weight of either 0 or 1, we can use 0-1 BFS instead of Dijkstra's Algorithm. 0-1 BFS uses a deque to process vertices.
Suppose we are at vertex u and there is an edge from u to v.
If the edge has weight 0, the distance does not increase. Add v to the front of the deque.
If the edge has weight 1, the distance increases by 1. Add v to the back of the deque.
This ensures that vertices with smaller distances are processed earlier.
Create a weighted graph by adding u -> v with cost 0 and v -> u with cost 1 for every edge.
Initialize dist[src] = 0 and all other distances to infinity.
Add src to a deque.
Remove vertices from the front and update their neighbors if a shorter distance is found.
Add a neighbor to the front for cost 0 and to the back for cost 1.
Return dist[dst] if reachable; otherwise, return -1.
2 -> 3 has cost 1 -> dist[3] = 1 -> add 3 to back.
deque = [3]
Step 3: Reach 3
dist[3] = 1
The path becomes: 1 -> 2 -> 3
The original edge 3 -> 2 is reversed to 2 -> 3.
Therefore, the minimum number of reversals is: 1
C++
#include<bits/stdc++.h>usingnamespacestd;// Function to find the minimum number of edge reversals.intminimumEdgeReversal(vector<vector<int>>&edges,intn,intsrc,intdst){vector<vector<pair<int,int>>>adj(n+1);// Create adjacency list with both directions.for(auto&edge:edges){intu=edge[0];intv=edge[1];// Original direction requires no reversal.adj[u].push_back({v,0});// Reverse direction requires one reversal.adj[v].push_back({u,1});}// Store the minimum reversals required to reach each node.vector<int>dist(n+1,INT_MAX);deque<int>dq;// Distance of source is 0.dist[src]=0;dq.push_front(src);// Apply 0-1 BFS.while(!dq.empty()){intnode=dq.front();dq.pop_front();// Explore all adjacent nodes.for(auto&edge:adj[node]){intnext=edge.first;intcost=edge.second;// Update the distance if a better path is found.if(dist[node]+cost<dist[next]){dist[next]=dist[node]+cost;// Process zero-cost edges first.if(cost==0)dq.push_front(next);elsedq.push_back(next);}}}// No path exists from src to dst.if(dist[dst]==INT_MAX)return-1;returndist[dst];}intmain(){intn=3;vector<vector<int>>edges={{1,2},{3,2}};intsrc=1;intdst=3;cout<<minimumEdgeReversal(edges,n,src,dst);return0;}
Java
importjava.util.ArrayList;importjava.util.Arrays;importjava.util.Deque;importjava.util.ArrayDeque;classGFG{// Function to find the minimum number of edge reversals.staticintminimumEdgeReversal(int[][]edges,intn,intsrc,intdst){ArrayList<ArrayList<int[]>>adj=newArrayList<>();for(inti=0;i<=n;i++)adj.add(newArrayList<>());// Create adjacency list with both directions.for(int[]edge:edges){intu=edge[0];intv=edge[1];// Original direction requires no reversal.adj.get(u).add(newint[]{v,0});// Reverse direction requires one reversal.adj.get(v).add(newint[]{u,1});}// Store the minimum reversals required to reach each node.int[]dist=newint[n+1];Arrays.fill(dist,Integer.MAX_VALUE);Deque<Integer>dq=newArrayDeque<>();// Distance of source is 0.dist[src]=0;dq.addFirst(src);// Apply 0-1 BFS.while(!dq.isEmpty()){intnode=dq.removeFirst();// Explore all adjacent nodes.for(int[]edge:adj.get(node)){intnext=edge[0];intcost=edge[1];// Update the distance if a better path is found.if(dist[node]+cost<dist[next]){dist[next]=dist[node]+cost;// Process zero-cost edges first.if(cost==0)dq.addFirst(next);elsedq.addLast(next);}}}// No path exists from src to dst.if(dist[dst]==Integer.MAX_VALUE)return-1;returndist[dst];}publicstaticvoidmain(String[]args){intn=3;int[][]edges={{1,2},{3,2}};intsrc=1;intdst=3;System.out.println(minimumEdgeReversal(edges,n,src,dst));}}
Python
fromcollectionsimportdeque# Function to find the minimum number of edge reversals.defminimumEdgeReversal(edges,n,src,dst):adj=[[]for_inrange(n+1)]# Create adjacency list with both directions.foredgeinedges:u=edge[0]v=edge[1]# Original direction requires no reversal.adj[u].append([v,0])# Reverse direction requires one reversal.adj[v].append([u,1])# Store the minimum reversals required to reach each node.dist=[float('inf')]*(n+1)dq=deque()# Distance of source is 0.dist[src]=0dq.appendleft(src)# Apply 0-1 BFS.whiledq:node=dq.popleft()# Explore all adjacent nodes.foredgeinadj[node]:next=edge[0]cost=edge[1]# Update the distance if a better path is found.ifdist[node]+cost<dist[next]:dist[next]=dist[node]+cost# Process zero-cost edges first.ifcost==0:dq.appendleft(next)else:dq.append(next)# No path exists from src to dst.ifdist[dst]==float('inf'):return-1returndist[dst]if__name__=="__main__":n=3edges=[[1,2],[3,2]]src=1dst=3print(minimumEdgeReversal(edges,n,src,dst))
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Function to find the minimum number of edge reversals.staticintminimumEdgeReversal(int[][]edges,intn,intsrc,intdst){List<List<int[]>>adj=newList<List<int[]>>();for(inti=0;i<=n;i++)adj.Add(newList<int[]>());// Create adjacency list with both directions.foreach(int[]edgeinedges){intu=edge[0];intv=edge[1];// Original direction requires no reversal.adj[u].Add(newint[]{v,0});// Reverse direction requires one reversal.adj[v].Add(newint[]{u,1});}// Store the minimum reversals required to reach each node.int[]dist=newint[n+1];Array.Fill(dist,int.MaxValue);LinkedList<int>dq=newLinkedList<int>();// Distance of source is 0.dist[src]=0;dq.AddFirst(src);// Apply 0-1 BFS.while(dq.Count>0){intnode=dq.First.Value;dq.RemoveFirst();// Explore all adjacent nodes.foreach(int[]edgeinadj[node]){intnext=edge[0];intcost=edge[1];// Update the distance if a better path is found.if(dist[node]+cost<dist[next]){dist[next]=dist[node]+cost;// Process zero-cost edges first.if(cost==0)dq.AddFirst(next);elsedq.AddLast(next);}}}// No path exists from src to dst.if(dist[dst]==int.MaxValue)return-1;returndist[dst];}publicstaticvoidMain(){intn=3;int[][]edges={newint[]{1,2},newint[]{3,2}};intsrc=1;intdst=3;Console.WriteLine(minimumEdgeReversal(edges,n,src,dst));}}
JavaScript
functionminimumEdgeReversal(edges,n,src,dst){constadj=Array.from({length:n+1},()=>[]);for(const[u,v]ofedges){// Original edge has zero reversal cost.adj[u].push([v,0]);// Reversed edge costs one reversal.adj[v].push([u,1]);}constdist=newArray(n+1).fill(Number.MAX_SAFE_INTEGER);constdq=[];dist[src]=0;dq.unshift(src);while(dq.length){constnode=dq.shift();for(const[next,wt]ofadj[node]){if(dist[node]+wt<dist[next]){dist[next]=dist[node]+wt;// Prioritize zero-cost edges in 0-1 BFS.if(wt===0)dq.unshift(next);elsedq.push(next);}}}returndist[dst]===Number.MAX_SAFE_INTEGER?-1:dist[dst];}// Driver codeletn=3;letedges=[[1,2],[3,2]];letsrc=1;letdst=3;console.log(minimumEdgeReversal(edges,n,src,dst));