Minimum cost path from source node to destination node via K intermediate nodes

Given a Graph consisting of N vertices and M weighted edges and an array edges[][], with each row representing the two vertices connected by the edge and the weight of the edge, the task is to find the path with the least sum of weights from a given source vertex src to a given destination vertex dst, made up of K intermediate vertices. If no such path exists, then print -1.
Examples:
Input: N = 3, M = 3, src = 0, dst = 2, K = 1, edges[] = {{0, 1, 100}, {1, 2, 100}, {0, 2, 500}}
Output: 200
Explanation:Â The path 0 -> 1 -> 2 is the least weighted sum (= 100 + 100 = 200) path connecting src (= 0) and dst(= 2) with exactly K (= 1) intermediate vertex.Input: N = 3, M = 3, src = 0, dst = 2, K = 0, edges[] = { { 0, 1, 100 }, { 1, 2, 100 }, { 0, 2, 500 } }
Output: 500
Explanation:Â The direct edge 0 -> 2 with weight 500 is the required path.
Approach: The given problem can be solved using Priority Queue and perform BFS. Follow the steps below to solve this problem:
- Initialize a priority queue to store the tuples {cost to reach this vertex, vertex, number of stops}.
- Push {0, src, k+1} as the first starting point.
- Pop-out the top element of priority queue. If all stops are exhausted, then repeat this step.
- If the destination is reached, then print the cost to reach the current vertex.
- Otherwise, find the neighbor of this vertex which required the smallest cost to reach that vertex. Push it into the priority queue.
- Repeat from step 2.
- If no path is found after performing the above steps, print -1.
Below is the implementation of the above approach:
C++
// C++ program for the above approach#include <bits/stdc++.h>using namespace std;Â
// Function to find the minimum cost path// from the source vertex to destination// vertex via K intermediate verticesint leastWeightedSumPath(int n,                         vector<vector<int> >& edges,                         int src, int dst, int K){    // Initialize the adjacency list    unordered_map<int,                  vector<pair<int, int> > >        graph;Â
    // Generate the adjacency list    for (vector<int>& edge : edges) {        graph[edge[0]].push_back(            make_pair(edge[1], edge[2]));    }Â
    // Initialize the minimum priority queue    priority_queue<vector<int>, vector<vector<int> >,                   greater<vector<int> > >        pq;Â
    // Stores the minimum cost to    // travel between vertices via    // K intermediate nodes    vector<vector<int> > costs(n,                               vector<int>(                                   K + 2, INT_MAX));Â
    costs[src][K + 1] = 0;Â
    // Push the starting vertex,    // cost to reach and the number    // of remaining vertices    pq.push({ 0, src, K + 1 });Â
    while (!pq.empty()) {        // Pop the top element        // of the stack        auto top = pq.top();Â
        pq.pop();Â
        // If destination is reached        if (top[1] == dst)Â
            // Return the cost            return top[0];Â
        // If all stops are exhausted        if (top[2] == 0)            continue;Â
        // Find the neighbour with minimum cost        for (auto neighbor : graph[top[1]]) {Â
            // Pruning            if (costs[neighbor.first][top[2] - 1]                < neighbor.second + top[0]) {                continue;            }Â
            // Update cost            costs[neighbor.first][top[2] - 1]                = neighbor.second + top[0];Â
            // Update priority queue            pq.push({ neighbor.second + top[0],                      neighbor.first, top[2] - 1 });        }    }Â
    // If no path exists    return -1;}Â
// Driver Codeint main(){    int n = 3, src = 0, dst = 2, k = 1;    vector<vector<int> > edges        = { { 0, 1, 100 },            { 1, 2, 100 },            { 0, 2, 500 } };Â
    // Function Call to find the path    // from src to dist via k nodes    // having least sum of weights    cout << leastWeightedSumPath(n, edges,                                 src, dst, k);Â
    return 0;} |
Java
// Java code to implement the approachimport java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.PriorityQueue;Â
class GFG {    // Function to find the minimum cost path    // from the source vertex to destination    // vertex via K intermediate vertices    static int    LeastWeightedSumPath(int n, List<List<Integer> > edges,                         int src, int dst, int K)    {        // Initialize the adjacency list        var graph = new ArrayList<List<int[]> >(            Collections.nCopies(n, null));Â
        // Generate the adjacency list        for (int i = 0; i < edges.size(); i++) {            var edge = edges.get(i);            if (graph.get(edge.get(0)) == null) {                graph.set(edge.get(0),                          new ArrayList<int[]>());            }            graph.get(edge.get(0))                .add(                    new int[] { edge.get(1), edge.get(2) });        }Â
        // Initialize the minimum priority queue        var pq = new PriorityQueue<int[]>(            (i1, i2) -> i1[0] - i2[0]);Â
        // Stores the minimum cost to        // travel between vertices via        // K intermediate nodes        var costs = new int[n][K + 2];Â
        for (int i = 0; i < n; i++) {            for (int j = 0; j < K + 2; j++) {                costs[i][j] = Integer.MAX_VALUE;            }        }Â
        costs[src][K + 1] = 0;Â
        // Push the starting vertex,        // cost to reach and the number        // of remaining vertices        pq.offer(new int[] { 0, src, K + 1 });Â
        while (!pq.isEmpty()) {            // Pop the top element            // of the queue            var top = pq.poll();Â
            // If destination is reached            if (top[1] == dst) {                // Return the cost                return top[0];            }Â
            // If all stops are exhausted            if (top[2] == 0) {                continue;            }Â
            // Find the neighbour with minimum cost            if (graph.get(top[1]) != null) {                for (var neighbor : graph.get(top[1])) {Â
                    // Pruning                    if (costs[neighbor[0]][top[2] - 1]                        < neighbor[1] + top[0]) {                        continue;                    }Â
                    // Update cost                    costs[neighbor[0]][top[2] - 1]                        = neighbor[1] + top[0];Â
                    // Update priority queue                    pq.offer(new int[] {                        neighbor[1] + top[0], neighbor[0],                        top[2] - 1 });                }            }        }Â
        // If no path exists        return -1;    }Â
    // Driver Code    public static void main(String[] args)    {        int n = 3, src = 0, dst = 2, k = 1;        var edges = new ArrayList<List<Integer> >();        edges.add(List.of(0, 1, 100));        edges.add(List.of(1, 2, 100));        edges.add(List.of(0, 2, 500));Â
        // Function Call to find the path        // from src to dist via k nodes        // having least sum of weights        System.out.println(            LeastWeightedSumPath(n, edges, src, dst, k));    }}Â
// This code is contributed by phasing17 |
Python3
# Python3 program for the above approachÂ
# Function to find the minimum cost path# from the source vertex to destination# vertex via K intermediate verticesdef leastWeightedSumPath(n, edges, src, dst, K):Â Â Â Â graph = [[] for i in range(3)]Â
    # Generate the adjacency list    for edge in edges:        graph[edge[0]].append([edge[1], edge[2]])Â
    # Initialize the minimum priority queue    pq = []Â
    # Stores the minimum cost to    # travel between vertices via    # K intermediate nodes    costs = [[10**9 for i in range(K + 2)] for i in range(n)]Â
    costs[src][K + 1] = 0Â
    # Push the starting vertex,    # cost to reach and the number    # of remaining vertices    pq.append([ 0, src, K + 1 ])Â
    pq = sorted(pq)[::-1]Â
    while (len(pq) > 0):               # Pop the top element        # of the stack        top = pq[-1]Â
        del pq[-1]Â
        # If destination is reached        if (top[1] == dst):                       # Return the cost            return top[0]Â
        # If all stops are exhausted        if (top[2] == 0):            continueÂ
        # Find the neighbour with minimum cost        for neighbor in graph[top[1]]:Â
            # Pruning            if (costs[neighbor[0]][top[2] - 1] < neighbor[1] + top[0]):                continueÂ
            # Update cost            costs[neighbor[0]][top[2] - 1] = neighbor[1]+ top[0]Â
            # Update priority queue            pq.append([neighbor[1]+ top[0],neighbor[0], top[2] - 1])        pq = sorted(pq)[::-1]Â
    # If no path exists    return -1Â
# Driver Codeif __name__ == '__main__':    n, src, dst, k = 3, 0, 2, 1    edges = [ [ 0, 1, 100 ],            [ 1, 2, 100 ],            [ 0, 2, 500 ] ]Â
    # Function Call to find the path    # from src to dist via k nodes    # having least sum of weights    print (leastWeightedSumPath(n, edges, src, dst, k))Â
# This code is contributed by mohit kumar 29. |
C#
using System;using System.Collections.Generic;Â
class GFG {    // Function to find the minimum cost path    // from the source vertex to destination    // vertex via K intermediate vertices    static int LeastWeightedSumPath(int n, List<List<int>> edges,                                     int src, int dst, int K) {        // Initialize the adjacency list        var graph = new Dictionary<int, List<Tuple<int, int>>>();Â
        // Generate the adjacency list        for (int i = 0; i < edges.Count; i++) {            var edge = edges[i];            if (!graph.ContainsKey(edge[0])) {                graph[edge[0]] = new List<Tuple<int, int>>();            }            graph[edge[0]].Add(new Tuple<int, int>(edge[1], edge[2]));        }Â
        // Initialize the minimum priority queue        var pq = new SortedSet<Tuple<int, int, int>>(            Comparer<Tuple<int, int, int>>.Create((i1, i2) =>                                                   i1.Item1.CompareTo(i2.Item1)));Â
        // Stores the minimum cost to        // travel between vertices via        // K intermediate nodes        var costs = new int[n, K + 2];Â
        for (int i = 0; i < n; i++) {            for (int j = 0; j < K + 2; j++) {                costs[i, j] = int.MaxValue;            }        }Â
        costs[src, K + 1] = 0;Â
        // Push the starting vertex,        // cost to reach and the number        // of remaining vertices        pq.Add(new Tuple<int, int, int>(0, src, K + 1));Â
        while (pq.Count > 0) {            // Pop the top element            // of the stack            var top = pq.Min;            pq.Remove(top);Â
            // If destination is reached            if (top.Item2 == dst) {                // Return the cost                return top.Item1;            }Â
            // If all stops are exhausted            if (top.Item3 == 0) {                continue;            }Â
            // Find the neighbour with minimum cost            if (graph.ContainsKey(top.Item2)) {                foreach (var neighbor in graph[top.Item2]) {Â
                    // Pruning                    if (costs[neighbor.Item1, top.Item3 - 1] < neighbor.Item2 + top.Item1) {                        continue;                    }Â
                    // Update cost                    costs[neighbor.Item1, top.Item3 - 1] = neighbor.Item2 + top.Item1;Â
                    // Update priority queue                    pq.Add(new Tuple<int, int, int>(neighbor.Item2 + top.Item1, neighbor.Item1, top.Item3 - 1));                }            }        }Â
        // If no path exists        return -1;    }Â
    // Driver Code    static void Main() {        int n = 3, src = 0, dst = 2, k = 1;        var edges = new List<List<int>>() {            new List<int> { 0, 1, 100 },            new List<int> { 1, 2, 100 },            new List<int> { 0, 2, 500 }        };Â
        // Function Call to find the path        // from src to dist via k nodes        // having least sum of weights        Console.WriteLine(LeastWeightedSumPath(n, edges, src, dst, k));    }} |
Javascript
<script>// Javascript program for the above approachÂ
// Function to find the minimum cost path// from the source vertex to destination// vertex via K intermediate verticesfunction leastWeightedSumPath(n, edges, src, dst, K){Â
    // Initialize the adjacency list    var graph = new Map();Â
    // Generate the adjacency list    for (var edge of edges) {        if(!graph.has(edge[0]))            graph.set(edge[0], new Array())        var tmp = graph.get(edge[0]);        tmp.push([edge[1], edge[2]]);        graph.set(edge[0],tmp);    }Â
    // Initialize the minimum priority queue    var pq = [];Â
    // Stores the minimum cost to    // travel between vertices via    // K intermediate nodes    var costs = Array.from(Array(n+1), ()=>Array(K+2).fill(1000000000));    costs[src][K + 1] = 0;Â
    // Push the starting vertex,    // cost to reach and the number    // of remaining vertices    pq.push([ 0, src, K + 1 ]);Â
    while (pq.length!=0) {        // Pop the top element        // of the stack        var top = pq[pq.length-1];Â
        pq.pop();Â
        // If destination is reached        if (top[1] == dst)Â
            // Return the cost            return top[0];Â
        // If all stops are exhausted        if (top[2] == 0)            continue;Â
        if(graph.has(top[1]))        {        // Find the neighbour with minimum cost        for (var neighbor of graph.get(top[1])) {                        // Pruning            if (costs[neighbor[0]][top[2] - 1]                < neighbor[1] + top[0]) {                continue;            }Â
            // Update cost            costs[neighbor[0]][top[2] - 1]                = neighbor[1] + top[0];Â
            // Update priority queue            pq.push([neighbor[1] + top[0],                      neighbor[0], top[2] - 1 ]);        }        }        pq.sort((a,b)=>{            if(a[0]==b[0])             return b[1]-a[1]            return b[0]-a[0];        });    }Â
    // If no path exists    return -1;}Â
// Driver Codevar n = 3, src = 0, dst = 2, k = 1;var edges    = [ [ 0, 1, 100 ],        [ 1, 2, 100 ],        [ 0, 2, 500 ] ];// Function Call to find the path// from src to dist via k nodes// having least sum of weightsdocument.write(leastWeightedSumPath(n, edges,                             src, dst, k));Â
// This code is contributed by rrrtnx.</script> |
Â
Â
200
Â
Time Complexity : O(N * log N)Â
Auxiliary Space: O(N)Â Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



