Shortest path in a graph from a source S to destination D with exactly K edges for multiple Queries
Given a graph with N nodes, a node S and Q queries each consisting of a node D and K, the task is to find the shortest path consisting of exactly K edges from node S to node D for each query. If no such path exists then print -1.
Note: K will always be lesser than 2 * N.
Examples:
Input: N = 3, edges[][] = {{1, 2, 5}, {2, 3, 3}, {3, 1, 4}}, S = 1, Q = {{1, 0}, {2, 1}, {3, 1}, {3, 2}, {3, 5}}
Output: 0 5 -1 8 20
1. The shortest path from 1 to 1 using 0 edge will be 0.
2. The shortest path from 1 to 2 using 1 edge will be 5 i.e 1->2.
3. No path of 1 edge exists between nodes 1 and 3.
4. The shortest path from 1 to 3 using 2 edges will be 8 i.e 1->2->3.
5. The shortest path from 1 to 3 using 5 edges will be 20 i.e 1->2->3->1->2->3.
Input: N = 4, edges[][] = {{1, 2, 8}, {2, 3, 5}, {3, 4, 7}}, S = 1, Q = {{1, 0}, {2, 1}, {3, 1}, {3, 2}, {4, 5}}
Output: 0 8 -1 13 -1
Approach:
- This problem can be solved with the help of dynamic programming to create a linear solution.
- Initialize a 2-d array, dp[N][2*N] with initial value as ‘inf’ except dp[S][0] as 0.
- Pre-process the graph to find the shortest distance of each and every node from the source for every edge length between {0 to N-1}. The array dp[][] will be used to store the results of the pre-processing.
- For the pre-processing, run a loop for J in the range [1, 2*N-1] to find the dp[X][J] for each edge in the graph, where dp[X][J] be the shortest path from node ‘S’ to node ‘X’ using exactly ‘J’ edges in total.
- We can find dp[X][J+1] with the help of a recurrence relation:
dp[ edge.second ][ i ] = min(dp[ edge.second ][ i ], dp[ edge.first ][ i-1 ] + weight(edge))
- For every query in Q, if(dp[X][k] == inf) then return -1, else return dp[X][k]
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define inf 100000000
void ansQueries( int s,
vector<pair<pair< int , int >, int > > ed,
int n, vector<pair< int , int > > q)
{
int dp[n + 1][2 * n];
for ( int i = 0; i <= n; i++)
dp[i][0] = inf;
dp[s][0] = 0;
for ( int i = 1; i <= 2 * n - 1; i++) {
for ( int j = 0; j <= n; j++)
dp[j][i] = inf;
for ( auto it : ed) {
dp[it.first.second][i]
= min(
dp[it.first.second][i],
dp[it.first.first][i - 1] + it.second);
}
}
for ( int i = 0; i < q.size(); i++) {
if (dp[q[i].first][q[i].second] == inf)
cout << -1 << endl;
else
cout << dp[q[i].first][q[i].second]
<< endl;
}
}
int main()
{
int n = 3;
vector<pair<pair< int , int >, int > > ed;
ed = { { { 1, 2 }, 5 },
{ { 2, 3 }, 3 },
{ { 3, 1 }, 4 } };
int s = 1;
vector<pair< int , int > > q = { { 1, 0 },
{ 2, 1 },
{ 3, 1 },
{ 3, 2 },
{ 3, 5 } };
ansQueries(s, ed, n, q);
return 0;
}
|
Java
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG{
static int inf = 100000000 ;
static void ansQueries( int s,
int [][] ed,
int n, int [][] q)
{
int [][] dp = new int [n + 1 ][ 2 * n];
for ( int i = 0 ; i <= n; i++)
dp[i][ 0 ] = inf;
dp[s][ 0 ] = 0 ;
for ( int i = 1 ; i <= 2 * n - 1 ; i++)
{
for ( int j = 0 ; j <= n; j++)
dp[j][i] = inf;
for ( int [] it : ed)
{
dp[it[ 1 ]][i] = Math.min(dp[it[ 1 ]][i],
dp[it[ 0 ]][i - 1 ] +
it[ 2 ]);
}
}
for ( int i = 0 ; i < q.length; i++)
{
if (dp[q[i][ 0 ]][q[i][ 1 ]] == inf)
System.out.println(- 1 );
else
System.out.println(dp[q[i][ 0 ]][q[i][ 1 ]]);
}
}
public static void main(String[] args)
{
int n = 3 ;
int [][] ed = { { 1 , 2 , 5 },
{ 2 , 3 , 3 },
{ 3 , 1 , 4 } };
int s = 1 ;
int [][] q = { { 1 , 0 },
{ 2 , 1 },
{ 3 , 1 },
{ 3 , 2 },
{ 3 , 5 } };
ansQueries(s, ed, n, q);
}
}
|
Python3
import sys,numpy as np
inf = sys.maxsize;
def ansQueries(s, ed, n, q) :
dp = np.zeros((n + 1 , 2 * n));
for i in range (n + 1 ) :
dp[i][ 0 ] = inf;
dp[s][ 0 ] = 0 ;
for i in range ( 1 , 2 * n) :
for j in range ( n + 1 ) :
dp[j][i] = inf;
for it in ed :
dp[it[ 1 ]][i] = min ( dp[it[ 1 ]][i],
dp[it[ 0 ]][i - 1 ] + ed[it]);
for i in range ( len (q)) :
if (dp[q[i][ 0 ]][q[i][ 1 ]] = = inf) :
print ( - 1 );
else :
print (dp[q[i][ 0 ]][q[i][ 1 ]]);
if __name__ = = "__main__" :
n = 3 ;
ed = { ( 1 , 2 ) : 5 ,
( 2 , 3 ) : 3 ,
( 3 , 1 ) : 4 };
s = 1 ;
q = [
( 1 , 0 ),
( 2 , 1 ),
( 3 , 1 ),
( 3 , 2 ),
( 3 , 5 )
];
ansQueries(s, ed, n, q);
|
C#
using System;
class GFG
{
static int inf = 100000000;
static void ansQueries( int s, int [][] ed, int n, int [][] q)
{
int [, ] dp = new int [n + 1, 2 * n];
for ( int i = 0; i <= n; i++)
dp[i, 0] = inf;
dp[s, 0] = 0;
for ( int i = 1; i <= 2 * n - 1; i++)
{
for ( int j = 0; j <= n; j++)
dp[j, i] = inf;
foreach ( int [] it in ed)
{
dp[it[1], i] = Math.Min(dp[it[1], i],
dp[it[0], i - 1] + it[2]);
}
}
for ( int i = 0; i < q.Length; i++)
{
if (dp[q[i][0], q[i][1]] == inf)
Console.WriteLine(-1);
else
Console.WriteLine(dp[q[i][0], q[i][1]]);
}
}
public static void Main( string [] args)
{
int n = 3;
int [][] ed = {
new int [3]{1, 2, 5},
new int [3]{2, 3, 3},
new int [3]{3, 1, 4}
};
int s = 1;
int [][] q = {
new int [2]{1, 0},
new int [2]{2, 1},
new int [2]{3, 1},
new int [2]{3, 2},
new int [2]{3, 5}
};
ansQueries(s, ed, n, q);
}
}
|
Javascript
<script>
var inf = 100000000;
function ansQueries( s, ed, n, q)
{
var dp = Array.from(Array(n+1), ()=> Array(2*n));
for ( var i = 0; i <= n; i++)
dp[i][0] = inf;
dp[s][0] = 0;
for ( var i = 1; i <= 2 * n - 1; i++) {
for ( var j = 0; j <= n; j++)
dp[j][i] = inf;
for ( var it =0; it<ed.length; it++)
{
dp[ed[it][0][1]][i]
= Math.min(
dp[ed[it][0][1]][i],
dp[ed[it][0][0]][i - 1] + ed[it][1]);
}
}
for ( var i = 0; i < q.length; i++) {
if (dp[q[i][0]][q[i][1]] == inf)
document.write( -1+ "<br>" );
else
document.write( dp[q[i][0]][q[i][1]]+ "<br>" );
}
}
var n = 3;
var ed;
ed = [ [ [ 1, 2 ], 5 ],
[ [ 2, 3 ], 3 ],
[ [ 3, 1 ], 4 ] ];
var s = 1;
var q = [ [ 1, 0 ],
[ 2, 1 ],
[ 3, 1 ],
[ 3, 2 ],
[ 3, 5 ] ];
ansQueries(s, ed, n, q);
</script>
|
Time Complexity: O(Q + N*E)
Space Complexity: O(N*N)
Last Updated :
13 May, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...