Shortest path between two cities without running out of fuel
Last Updated : 23 Jul, 2025
Given a country with N cities connected by M bi-directional roads given in the form of 2D array roads[][], where P cities have fuel stations and (N - P) cities do not. The task is to compute the shortest path from City A to City B, such that a car with maximum fuel capacity of "capacity" can travel without running out of fuel.
Note: 1 unit of fuel is used to travel through any road.
Examples:
Input: N = 7, M = 6, roads = [[1, 2], [2, 3], [3, 4], [4, 5], [4, 6], [6, 7]], A = 1, B = 7, capacity = 4, P = 1, fuel stations = [5]
graph
Output: 7 Explanation: As the shortest path is 1-2-3-4-5-4-6-7
Input: N = 7, M = 6, roads = [[1, 2], [2, 3], [3, 4], [4, 5], [4, 6], [6, 7]], A = 1, B = 7, capacity = 4, P = 2, fuel stations = [5,6] Output: 5 Explanation: As the shortest path is 1-2-3-4-6-7
Approach: To solve the problem, follow the below idea:
We can solve the problem using Breadth First Search. Start a BFS from source node by pushing the current node along with the remaining fuel in the queue. If at any node, the fuel goes to 0, we eliminate that path i.e. we don't add that node's neighbors in the queue again. At the end return the path which takes you to destination while maintaining the fuel capacity.
Step-by-step algorithm:
Build Adjacency List: Create an empty list (adj) for the adjacency list. Iterate over bi-directional roads and add edges to the adjacency list.
Initialize Capacity Array: Create an array (caps) to represent fuel capacity at each city. Mark cities with fuel stations by setting caps[city] = capacity.
Initialize Fuel Array: Create an array (fuel) to represent the current fuel level at each city. Mark the starting city with the full fuel capacity.
Initialize Queue for BFS: Create a deque (que) and add the starting city with distance 0.
Apply BFS: Use a while loop to iterate until the queue is empty. Pop a pair (distance, node) from the queue. If the current node is the destination, return the distance. Iterate over neighbors of the current node, updating their fuel levels under certain conditions. If the condition is true, update the fuel level and enqueue the neighbor with an incremented distance.
Return -1 if Path Not Found: If the loop completes without reaching the destination, return -1, indicating no path.
Below is the implementation of the algorithm:
C++
#include<iostream>#include<vector>#include<queue>#include<algorithm>usingnamespacestd;classSolution{public:intfindMinRoute(intn,vector<vector<int>>&roads,vector<int>&fuelStations,intsource,intdestination,intcapacity){// Defining the adjacency listvector<vector<int>>adj(n+1,vector<int>());// Building the adjacency list from given roadsfor(auto&road:roads){intu=road[0];intv=road[1];adj[u].push_back(v);adj[v].push_back(u);}// Initializing fuel capacities for each nodevector<int>caps(n+1,0);for(intnode:fuelStations){caps[node]=capacity;}// Initializing fuel levels for each nodevector<int>fuel(n+1,0);// Initializing the queue for BFS traversalqueue<pair<int,int>>queue;queue.push({0,source});fuel[source]=capacity;// BFS traversalwhile(!queue.empty()){autocurrent=queue.front();queue.pop();intdis=current.first;intnode=current.second;if(node==destination){returndis;}// Exploring neighbors of the current nodefor(intadjNode:adj[node]){// Calculating the new fuel level for the adjacent nodeintnewFuel=max(caps[adjNode],fuel[node]-1);// If the new fuel level is greater than the existing at the next nodeif(newFuel>fuel[adjNode]){// Update the fuel level and add the adjacent node to the queuefuel[adjNode]=newFuel;queue.push({dis+1,adjNode});}}}// If destination is not reachablereturn-1;}};// Example usageintmain(){intn=7;vector<vector<int>>roads={{1,2},{2,3},{3,4},{4,5},{4,6},{6,7}};intsource=1;intdestination=7;intcapacity=4;vector<int>fuelStations={5};cout<<Solution().findMinRoute(n,roads,fuelStations,source,destination,capacity)<<endl;return0;}
Java
importjava.util.*;classSolution{publicintfindMinRoute(intn,int[][]roads,List<Integer>fuelStations,intsource,intdestination,intcapacity){// Defining the adjacency listList<List<Integer>>adj=newArrayList<>();for(inti=0;i<=n;i++){adj.add(newArrayList<>());}// Building the adjacency list from given roadsfor(int[]road:roads){intu=road[0];intv=road[1];adj.get(u).add(v);adj.get(v).add(u);}// Initializing fuel capacities for each nodeint[]caps=newint[n+1];for(intnode:fuelStations){caps[node]=capacity;}// Initializing fuel levels for each nodeint[]fuel=newint[n+1];// Initializing the queue for BFS traversalQueue<int[]>queue=newLinkedList<>();queue.offer(newint[]{0,source});fuel[source]=capacity;// BFS traversalwhile(!queue.isEmpty()){int[]current=queue.poll();intdis=current[0];intnode=current[1];if(node==destination){returndis;}// Exploring neighbors of the current nodefor(intadjNode:adj.get(node)){// Calculating the new fuel level for the adjacent nodeintnewFuel=Math.max(caps[adjNode],fuel[node]-1);// If the new fuel level is greater than the existing at the next nodeif(newFuel>fuel[adjNode]){// Update the fuel level and add the adjacent node to the queuefuel[adjNode]=newFuel;queue.offer(newint[]{dis+1,adjNode});}}}// If destination is not reachablereturn-1;}// Example usagepublicstaticvoidmain(String[]args){intn=7;int[][]roads={{1,2},{2,3},{3,4},{4,5},{4,6},{6,7}};intsource=1;intdestination=7;intcapacity=4;List<Integer>fuelStations=Arrays.asList(5);System.out.println(newSolution().findMinRoute(n,roads,fuelStations,source,destination,capacity));}}// This code is contributed by shivamgupta0987654321
C#
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;classSolution{publicintFindMinRoute(intn,int[][]roads,List<int>fuelStations,intsource,intdestination,intcapacity){// Defining the adjacency listList<List<int>>adj=newList<List<int>>();for(inti=0;i<=n;i++){adj.Add(newList<int>());}// Building the adjacency list from given roadsforeach(varroadinroads){intu=road[0];intv=road[1];adj[u].Add(v);adj[v].Add(u);}// Initializing fuel capacities for each nodeint[]caps=newint[n+1];foreach(intnodeinfuelStations){caps[node]=capacity;}// Initializing fuel levels for each nodeint[]fuel=newint[n+1];// Initializing the queue for BFS traversalQueue<int[]>queue=newQueue<int[]>();queue.Enqueue(newint[]{0,source});fuel[source]=capacity;// BFS traversalwhile(queue.Count>0){int[]current=queue.Dequeue();intdis=current[0];intnode=current[1];if(node==destination){returndis;}// Exploring neighbors of the current nodeforeach(intadjNodeinadj[node]){// Calculating the new fuel level for the adjacent nodeintnewFuel=Math.Max(caps[adjNode],fuel[node]-1);// If the new fuel level is greater than the existing at the next nodeif(newFuel>fuel[adjNode]){// Update the fuel level and add the adjacent node to the queuefuel[adjNode]=newFuel;queue.Enqueue(newint[]{dis+1,adjNode});}}}// If destination is not reachablereturn-1;}// Example usagepublicstaticvoidMain(string[]args){intn=7;int[][]roads={newint[]{1,2},newint[]{2,3},newint[]{3,4},newint[]{4,5},newint[]{4,6},newint[]{6,7}};intsource=1;intdestination=7;intcapacity=4;List<int>fuelStations=newList<int>{5};Console.WriteLine(newSolution().FindMinRoute(n,roads,fuelStations,source,destination,capacity));}}
JavaScript
classSolution{findMinRoute(n,roads,fuelStations,source,destination,capacity){// Defining the adjacency listconstadj=newArray(n+1).fill(null).map(()=>[]);// Building the adjacency list from given roadsfor(const[u,v]ofroads){adj[u].push(v);adj[v].push(u);}// Initializing fuel capacities for each nodeconstcaps=newArray(n+1).fill(0);for(constnodeoffuelStations){caps[node]=capacity;}// Initializing fuel levels for each nodeconstfuel=newArray(n+1).fill(0);// Initializing the queue for BFS traversalconstqueue=[];queue.push([0,source]);fuel[source]=capacity;// BFS traversalwhile(queue.length>0){const[dis,node]=queue.shift();if(node===destination){returndis;}// Exploring neighbors of the current nodefor(constadjNodeofadj[node]){// Calculating the new fuel level for the adjacent nodeconstnewFuel=Math.max(caps[adjNode],fuel[node]-1);// If the new fuel level is greater than the existing at the next nodeif(newFuel>fuel[adjNode]){// Update the fuel level and add the adjacent node to the queuefuel[adjNode]=newFuel;queue.push([dis+1,adjNode]);}}}// If destination is not reachablereturn-1;}}// Example usageconstn=7;constroads=[[1,2],[2,3],[3,4],[4,5],[4,6],[6,7]];constsource=1;constdestination=7;constcapacity=4;constfuelStations=[5];console.log(newSolution().findMinRoute(n,roads,fuelStations,source,destination,capacity));
Python3
fromcollectionsimportdequeclassSolution:deffindMinRoute(self,n,roads,fuel_stations,source,destination,capacity):# Defining the adjacency listadj=[[]for_inrange(n+1)]# Building the adjacency list from given roadsforu,vinroads:adj[u].append(v)adj[v].append(u)# Initializing fuel capacities for each nodecaps=[0]*(n+1)fornodeinfuel_stations:caps[node]=capacity# Initializing fuel levels for each nodefuel=[0]*(n+1)# Initializing the queue for BFS traversalque=deque([(0,source)])fuel[source]=capacity# BFS traversalwhileque:dis,node=que.popleft()ifnode==destination:returndis# Exploring neighbors of the current nodeforadjNodeinadj[node]:# Calculating the new fuel level for the adjacent nodenew=max(caps[adjNode],fuel[node]-1)# If the new fuel level is greater than the existing at the next nodeifnew>fuel[adjNode]:# Update the fuel level and add the adjacent node to the queuefuel[adjNode]=newque.append((dis+1,adjNode))# If destination is not reachablereturn-1# Example usagen=7roads=[[1,2],[2,3],[3,4],[4,5],[4,6],[6,7]]A=1B=7capacity=4fuel_stations=[5]print(Solution().findMinRoute(n,roads,fuel_stations,A,B,capacity))
Output
7
Time Complexity: O(N + M) where N is the number of cities and M is the number of roads. Auxiliary Space: O(N)