Shortest path with exactly k edges in a directed and weighted graph

23 Jun, 2022
Given a directed and two vertices ‘u’ and ‘v’ in it, find shortest path from ‘u’ to ‘v’ with exactly k edges on the path.
The graph is given as adjacency matrix representation where value of graph[i][j] indicates the weight of an edge from vertex i to vertex j and a value INF(infinite) indicates no edge from i to j.
For example, consider the following graph. Let source ‘u’ be vertex 0, destination ‘v’ be 3 and k be 2. There are two walks of length 2, the walks are {0, 2, 3} and {0, 1, 3}. The shortest among the two is {0, 2, 3} and weight of path is 3+6 = 9.
The idea is to browse through all paths of length k from u to v using the approach discussed in the previous post and return weight of the shortest path. A simple solution is to start from u, go to all adjacent vertices, and recur for adjacent vertices with k as k-1, source as adjacent vertex and destination as v. Following are C++ and Java implementations of this simple solution. 
C++
Java
Python3
C#
Javascript
// C++ program to find shortest path with exactly k edges#include <bits/stdc++.h>using namespace std; // Define number of vertices in the graph and infinite value#define V 4#define INF INT_MAX // A naive recursive function to count walks from u to v with k edgesint shortestPath(int graph[][V], int u, int v, int k){   // Base cases   if (k == 0 && u == v)             return 0;   if (k == 1 && graph[u][v] != INF) return graph[u][v];   if (k <= 0)                       return INF;    // Initialize result   int res = INF;    // Go to all adjacents of u and recur   for (int i = 0; i < V; i++)   {       if (graph[u][i] != INF && u != i && v != i)       {           int rec_res = shortestPath(graph, i, v, k-1);           if (rec_res != INF)              res = min(res, graph[u][i] + rec_res);       }   }   return res;} // driver program to test above functionint main(){    /* Let us create the graph shown in above diagram*/     int graph[V][V] = { {0, 10, 3, 2},                        {INF, 0, INF, 7},                        {INF, INF, 0, 6},                        {INF, INF, INF, 0}                      };    int u = 0, v = 3, k = 2;    cout << "Weight of the shortest path is " <<          shortestPath(graph, u, v, k);    return 0;}
// Dynamic Programming based Java program to find shortest path// with exactly k edgesimport java.util.*;import java.lang.*;import java.io.*; class ShortestPath{    // Define number of vertices in the graph and infinite value    static final int V = 4;    static final int INF = Integer.MAX_VALUE;     // A naive recursive function to count walks from u to v    // with k edges    int shortestPath(int graph[][], int u, int v, int k)    {        // Base cases        if (k == 0 && u == v)             return 0;        if (k == 1 && graph[u][v] != INF) return graph[u][v];        if (k <= 0)                       return INF;         // Initialize result        int res = INF;         // Go to all adjacents of u and recur        for (int i = 0; i < V; i++)        {            if (graph[u][i] != INF && u != i && v != i)            {                int rec_res = shortestPath(graph, i, v, k-1);                if (rec_res != INF)                    res = Math.min(res, graph[u][i] + rec_res);            }        }        return res;    }     public static void main (String[] args)    {        /* Let us create the graph shown in above diagram*/        int graph[][] = new int[][]{ {0, 10, 3, 2},                                     {INF, 0, INF, 7},                                     {INF, INF, 0, 6},                                     {INF, INF, INF, 0}                                   };        ShortestPath t = new ShortestPath();        int u = 0, v = 3, k = 2;        System.out.println("Weight of the shortest path is "+                           t.shortestPath(graph, u, v, k));    }}
# Python3 program to find shortest path# with exactly k edges # Define number of vertices in the graph# and infinite value # A naive recursive function to count# walks from u to v with k edgesdef shortestPath(graph, u, v, k):    V = 4    INF = 999999999999         # Base cases    if k == 0 and u == v:        return 0    if k == 1 and graph[u][v] != INF:        return graph[u][v]    if k <= 0:        return INF # Initialize result    res = INF # Go to all adjacents of u and recur    for i in range(V):        if graph[u][i] != INF and u != i and v != i:            rec_res = shortestPath(graph, i, v, k - 1)            if rec_res != INF:                res = min(res, graph[u][i] + rec_res)    return res # Driver Codeif __name__ == '__main__':    INF = 999999999999         # Let us create the graph shown    # in above diagram    graph = [[0, 10, 3, 2],             [INF, 0, INF, 7],             [INF, INF, 0, 6],             [INF, INF, INF, 0]]    u = 0    v = 3    k = 2    print("Weight of the shortest path is",              shortestPath(graph, u, v, k)) # This code is contributed by PranchalK
// Dynamic Programming based C# program to// find shortest pathwith exactly k edgesusing System; class GFG{     // Define number of vertices in the// graph and infinite valueconst int V = 4;const int INF = Int32.MaxValue; // A naive recursive function to count// walks from u to v with k edgesint shortestPath(int[,] graph, int u,                 int v, int k){    // Base cases    if (k == 0 && u == v)         return 0;    if (k == 1 && graph[u, v] != INF) return graph[u, v];    if (k <= 0)                 return INF;     // Initialize result    int res = INF;     // Go to all adjacents of u and recur    for (int i = 0; i < V; i++)    {        if (graph[u, i] != INF && u != i && v != i)        {            int rec_res = shortestPath(graph, i, v, k - 1);            if (rec_res != INF)                res = Math.Min(res, graph[u, i] + rec_res);        }    }    return res;} // Driver Codepublic static void Main (){    /* Let us create the graph       shown in above diagram*/    int[,] graph = new int[,]{{0, 10, 3, 2},                              {INF, 0, INF, 7},                              {INF, INF, 0, 6},                              {INF, INF, INF, 0}};    GFG t = new GFG();    int u = 0, v = 3, k = 2;    Console.WriteLine("Weight of the shortest path is "+                      t.shortestPath(graph, u, v, k));}} // This code is contributed by Akanksha Rai
<script> // Dynamic Programming based Javascript// program to find shortest path// with exactly k edges // Define number of vertices in the graph and infinite valuelet V = 4;let INF = Number.MAX_VALUE; // A naive recursive function to count walks from u to v// with k edgesfunction shortestPath(graph,u,v,k){    // Base cases        if (k == 0 && u == v)             return 0;        if (k == 1 && graph[u][v] != INF) return graph[u][v];        if (k <= 0)                       return INF;           // Initialize result        let res = INF;           // Go to all adjacents of u and recur        for (let i = 0; i < V; i++)        {            if (graph[u][i] != INF && u != i && v != i)            {                let rec_res = shortestPath(graph, i, v, k-1);                if (rec_res != INF)                    res = Math.min(res, graph[u][i] + rec_res);            }        }        return res;} let graph=[[0, 10, 3, 2],[INF, 0, INF, 7],           [INF, INF, 0, 6],[INF, INF, INF, 0]]; let u = 0, v = 3, k = 2;document.write("Weight of the shortest path is "+                           shortestPath(graph, u, v, k));  // This code is contributed by rag2127 </script>
Weight of the shortest path is 9
The worst-case time complexity of the above function is O(Vk) where V is the number of vertices in the given graph. We can simply analyze the time complexity by drawing recursion tree. The worst occurs for a complete graph. In worst case, every internal node of recursion tree would have exactly V children. 
We can optimize the above solution using Dynamic Programming. The idea is to build a 3D table where first dimension is source, second dimension is destination, third dimension is number of edges from source to destination, and the value is the weight of the shortest path having exactly the number of edges, stored in the third dimension, from source to destination. Like other Dynamic Programming problems, we fill the 3D table in bottom-up manner.
C++
Java
Python3
C#
Javascript
// Dynamic Programming based C++ program to find shortest path with// exactly k edges#include <iostream>#include <climits>using namespace std; // Define number of vertices in the graph and infinite value#define V 4#define INF INT_MAX // A Dynamic programming based function to find the shortest path from// u to v with exactly k edges.int shortestPath(int graph[][V], int u, int v, int k){    // Table to be filled up using DP. The value sp[i][j][e] will store    // weight of the shortest path from i to j with exactly k edges    int sp[V][V][k+1];     // Loop for number of edges from 0 to k    for (int e = 0; e <= k; e++)    {        for (int i = 0; i < V; i++)  // for source        {            for (int j = 0; j < V; j++) // for destination            {                // initialize value                sp[i][j][e] = INF;                 // from base cases                if (e == 0 && i == j)                    sp[i][j][e] = 0;                if (e == 1 && graph[i][j] != INF)                    sp[i][j][e] = graph[i][j];                 //go to adjacent only when number of edges is more than 1                if (e > 1)                {                    for (int a = 0; a < V; a++)                    {                        // There should be an edge from i to a and a                        // should not be same as either i or j                        if (graph[i][a] != INF && i != a &&                            j!= a && sp[a][j][e-1] != INF)                          sp[i][j][e] = min(sp[i][j][e], graph[i][a] +                                                       sp[a][j][e-1]);                    }                }           }        }    }    return sp[u][v][k];} // driver program to test above functionint main(){    /* Let us create the graph shown in above diagram*/     int graph[V][V] = { {0, 10, 3, 2},                        {INF, 0, INF, 7},                        {INF, INF, 0, 6},                        {INF, INF, INF, 0}                      };    int u = 0, v = 3, k = 2;    cout << shortestPath(graph, u, v, k);    return 0;}
// Dynamic Programming based Java program to find shortest path with// exactly k edgesimport java.util.*;import java.lang.*;import java.io.*; class ShortestPath{    // Define number of vertices in the graph and infinite value    static final int V = 4;    static final int INF = Integer.MAX_VALUE;     // A Dynamic programming based function to find the shortest path    // from u to v with exactly k edges.    int shortestPath(int graph[][], int u, int v, int k)    {        // Table to be filled up using DP. The value sp[i][j][e] will        // store weight of the shortest path from i to j with exactly        // k edges        int sp[][][] = new int[V][V][k+1];         // Loop for number of edges from 0 to k        for (int e = 0; e <= k; e++)        {            for (int i = 0; i < V; i++)  // for source            {                for (int j = 0; j < V; j++) // for destination                {                    // initialize value                    sp[i][j][e] = INF;                     // from base cases                    if (e == 0 && i == j)                        sp[i][j][e] = 0;                    if (e == 1 && graph[i][j] != INF)                        sp[i][j][e] = graph[i][j];                     // go to adjacent only when number of edges is                    // more than 1                    if (e > 1)                    {                        for (int a = 0; a < V; a++)                        {                            // There should be an edge from i to a and                            // a should not be same as either i or j                            if (graph[i][a] != INF && i != a &&                                    j!= a && sp[a][j][e-1] != INF)                                sp[i][j][e] = Math.min(sp[i][j][e],                                          graph[i][a] + sp[a][j][e-1]);                        }                    }                }            }        }        return sp[u][v][k];    }     public static void main (String[] args)    {        /* Let us create the graph shown in above diagram*/        int graph[][] = new int[][]{ {0, 10, 3, 2},                                     {INF, 0, INF, 7},                                     {INF, INF, 0, 6},                                     {INF, INF, INF, 0}                                   };        ShortestPath t = new ShortestPath();        int u = 0, v = 3, k = 2;        System.out.println("Weight of the shortest path is "+                           t.shortestPath(graph, u, v, k));    }}//This code is contributed by Aakash Hasija
# Dynamic Programming based Python3# program to find shortest path with # A Dynamic programming based function# to find the shortest path from u to v# with exactly k edges.def shortestPath(graph, u, v, k):    global V, INF         # Table to be filled up using DP. The    # value sp[i][j][e] will store weight    # of the shortest path from i to j    # with exactly k edges    sp = [[None] * V for i in range(V)]    for i in range(V):        for j in range(V):            sp[i][j] = [None] * (k + 1)     # Loop for number of edges from 0 to k    for e in range(k + 1):        for i in range(V): # for source            for j in range(V): # for destination                             # initialize value                sp[i][j][e] = INF                 # from base cases                if (e == 0 and i == j):                    sp[i][j][e] = 0                if (e == 1 and graph[i][j] != INF):                    sp[i][j][e] = graph[i][j]                 # go to adjacent only when number                # of edges is more than 1                if (e > 1):                    for a in range(V):                                                 # There should be an edge from                        # i to a and a should not be                        # same as either i or j                        if (graph[i][a] != INF and i != a and                             j!= a and sp[a][j][e - 1] != INF):                            sp[i][j][e] = min(sp[i][j][e], graph[i][a] +                                              sp[a][j][e - 1])                             return sp[u][v][k] # Driver Code # Define number of vertices in# the graph and infinite valueV = 4INF = 999999999999 # Let us create the graph shown# in above diagramgraph = [[0, 10, 3, 2],         [INF, 0, INF, 7],         [INF, INF, 0, 6],         [INF, INF, INF, 0]]u = 0v = 3k = 2print("Weight of the shortest path is",          shortestPath(graph, u, v, k)) # This code is contributed by PranchalK
// Dynamic Programming based C# program to find// shortest path with exactly k edgesusing System; class GFG{     // Define number of vertices in the graph// and infinite valuestatic readonly int V = 4;static readonly int INF = int.MaxValue; // A Dynamic programming based function to// find the shortest path from u to v// with exactly k edges.int shortestPath(int [,]graph, int u, int v, int k){    // Table to be filled up using DP. The value    // sp[i][j][e] will store weight of the shortest    // path from i to j with exactly k edges    int [,,]sp = new int[V, V, k + 1];     // Loop for number of edges from 0 to k    for (int e = 0; e <= k; e++)    {        for (int i = 0; i < V; i++) // for source        {            for (int j = 0; j < V; j++) // for destination            {                // initialize value                sp[i, j, e] = INF;                 // from base cases                if (e == 0 && i == j)                    sp[i, j, e] = 0;                if (e == 1 && graph[i, j] != INF)                    sp[i, j, e] = graph[i, j];                 // go to adjacent only when number of                // edges is more than 1                if (e > 1)                {                    for (int a = 0; a < V; a++)                    {                        // There should be an edge from i to a and                        // a should not be same as either i or j                        if (graph[i, a] != INF && i != a &&                                j!= a && sp[a, j, e - 1] != INF)                            sp[i, j, e] = Math.Min(sp[i, j, e],                                          graph[i, a] + sp[a, j, e - 1]);                    }                }            }        }    }    return sp[u, v, k];} // Driver Codepublic static void Main(String[] args){    /* Let us create the graph shown in above diagram*/    int [,]graph = new int[,]{ {0, 10, 3, 2},                               {INF, 0, INF, 7},                               {INF, INF, 0, 6},                               {INF, INF, INF, 0} };    GFG t = new GFG();    int u = 0, v = 3, k = 2;    Console.WriteLine("Weight of the shortest path is "+                        t.shortestPath(graph, u, v, k));}} // This code is contributed by 29AjayKumar
<script>// Dynamic Programming based Javascript program to find shortest path with// exactly k edges // Define number of vertices in the graph and infinite valuelet V = 4;let INF = Number.MAX_VALUE; // A Dynamic programming based function to find the shortest path    // from u to v with exactly k edges.function shortestPath(graph, u, v, k){    // Table to be filled up using DP. The value sp[i][j][e] will        // store weight of the shortest path from i to j with exactly        // k edges        let sp = new Array(V);         for(let i = 0; i < V; i++)        {            sp[i] = new Array(V);            for(let j = 0; j < V; j++)            {                sp[i][j] = new Array(k + 1);                for(let l = 0; l < (k + 1); l++)                {                    sp[i][j][l] = 0;                }            }        }                 // Loop for number of edges from 0 to k        for (let e = 0; e <= k; e++)        {            for (let i = 0; i < V; i++)  // for source            {                for (let j = 0; j < V; j++) // for destination                {                    // initialize value                    sp[i][j][e] = INF;                      // from base cases                    if (e == 0 && i == j)                        sp[i][j][e] = 0;                    if (e == 1 && graph[i][j] != INF)                        sp[i][j][e] = graph[i][j];                      // go to adjacent only when number of edges is                    // more than 1                    if (e > 1)                    {                        for (let a = 0; a < V; a++)                        {                            // There should be an edge from i to a and                            // a should not be same as either i or j                            if (graph[i][a] != INF && i != a &&                                    j!= a && sp[a][j][e-1] != INF)                                sp[i][j][e] = Math.min(sp[i][j][e],                                          graph[i][a] + sp[a][j][e-1]);                        }                    }                }            }        }        return sp[u][v][k];} let graph = [[0, 10, 3, 2], [INF, 0, INF, 7], [INF, INF, 0, 6], [INF, INF, INF, 0]];let u = 0, v = 3, k = 2;document.write("Weight of the shortest path is "+                           shortestPath(graph, u, v, k)); // This code is contributed by avanitrachhadiya2155</script>
9
Time complexity of the above DP-based solution is O(V3K) which is much better than the naive solution.
29AjayKumar
PranchalKatiyar
Akanksha_Rai
rag2127
avanitrachhadiya2155
anikakapoor
eternalLearner
hardikkoriintern
Shortest Path
Dynamic Programming
Graph
Dynamic Programming
Graph
Shortest Path
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.