Open In App

Number of distinct Shortest Paths from Node 1 to N in a Weighted and Directed Graph

Last Updated : 28 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a directed and weighted graph of N nodes and M edges, the task is to count the number of shortest length paths between node 1 to N.

Examples:

Input: N = 4, M = 5, edges = {{1, 4, 5}, {1, 2, 4}, {2, 4, 5}, {1, 3, 2}, {3, 4, 3}}
Output: 2
Explanation: The number of shortest path from node 1 to node 4 is 2, having cost 5.

Input: N = 3, M = 2, edges = {{1, 2, 4}, {1, 3, 5}}
Output: 1

Approach: The problem can be solved by the Dijkstra algorithm. Use two arrays, say dist[] to store the shortest distance from the source vertex and paths[] of size N, to store the number of different shortest paths from the source vertex to vertex N. Follow these steps below for the approach.

  • Initialize a priority queue, say pq, to store the vertex number and its distance value.
  • Initialize a vector of zeroes, say paths[] of size N, and make paths[1] equals 1.
  • Initialize a vector  of large numbers(1e9), say dist[] of size N, and make dist[1] equal 0.
  • Iterate while pq is not empty.
    • Pop from the pq and store the vertex value in a variable, say u, and the distance value in the variable d.
    • If d is greater than u, then continue.
    • For every v of each vertex u, if dist[v] > dist[u]+ (edge cost of u and v), then decrease the dist[v] to dist[u] +(edge cost of u and v) and assign the number of paths of vertex u to the number of paths of vertex v.
    • For every v of each vertex u, if dist[v] = dist[u] + (edge cost of u and v), then add the number of paths of vertex u to the number of paths of vertex v.
  • Finally, print paths[N].

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
const int INF = 1e9;
const int MAXN = 1e5 + 1;
vector<vector<pair<int, int> > > g(MAXN);
vector<int> dist(MAXN);
vector<int> route(MAXN);
 
// Function to count number of shortest
// paths from node 1 to node N
void countDistinctShortestPaths(
    int n, int m, int edges[][3])
{
    // Storing the graph
    for (int i = 0; i < m; ++i) {
        int u = edges[i][0],
            v = edges[i][1],
            c = edges[i][2];
        g[u].push_back({ v, c });
    }
 
    // Initializing dis array to a
    // large value
    for (int i = 2; i <= n; ++i) {
        dist[i] = INF;
    }
 
    // Initialize a priority queue
    priority_queue<pair<int, int>,
                   vector<pair<int, int> >,
                   greater<pair<int, int> > >
        pq;
    pq.push({ 0, 1 });
 
    // Base Cases
    dist[1] = 0;
    route[1] = 1;
 
    // Loop while priority queue is
    // not empty
    while (!pq.empty()) {
        int d = pq.top().first;
        int u = pq.top().second;
        pq.pop();
 
        // if d is greater than distance
        // of the node
        if (d > dist[u])
            continue;
 
        // Traversing all its neighbours
        for (auto e : g[u]) {
            int v = e.first;
            int c = e.second;
            if (c + d > dist[v])
                continue;
 
            // Path found of same distance
            if (c + d == dist[v]) {
                route[v] += route[u];
            }
 
            // New path found for lesser
            // distance
            if (c + d < dist[v]) {
                dist[v] = c + d;
                route[v] = route[u];
 
                // Pushing in priority
                // queue
                pq.push({ dist[v], v });
            }
        }
    }
}
 
// Driver Code
int main()
{
    // Given Input
    int n = 4;
    int m = 5;
    int edges[m][3] = { { 1, 4, 5 },
                        { 1, 2, 4 },
                        { 2, 4, 5 },
                        { 1, 3, 2 },
                        { 3, 4, 3 } };
 
    // Function Call
    countDistinctShortestPaths(n, m, edges);
    cout << route[n] << endl;
 
    return 0;
}


Java




// Java program for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to count number of shortest paths from node
    // 1 to node N
    static void countDistinctShortestPaths(int n, int m,
                                           int[][] edges)
    {
        List<int[]>[] g = new List[n + 1];
        int[] dist = new int[n + 1];
        int[] route = new int[n + 1];
 
        // Storing the graph
        for (int i = 0; i < m; i++) {
            int u = edges[i][0];
            int v = edges[i][1];
            int c = edges[i][2];
            if (g[u] == null) {
                g[u] = new ArrayList<int[]>();
            }
            g[u].add(new int[] { v, c });
        }
 
        // Initializing dis array to a large value
        Arrays.fill(dist, Integer.MAX_VALUE);
 
        // Base Cases
        dist[1] = 0;
        route[1] = 1;
 
        // Loop while priority queue is not empty
        PriorityQueue<int[]> pq = new PriorityQueue<>(
            Comparator.comparingInt(a -> a[0]));
        pq.add(new int[] { 0, 1 });
        while (!pq.isEmpty()) {
            int[] poll = pq.poll();
            int d = poll[0];
            int u = poll[1];
 
            // if d is greater than distance of the node
            if (d > dist[u])
                continue;
 
            // Traversing all its neighbours
            if (g[u] != null) {
                for (int i = 0; i < g[u].size(); i++) {
                    int[] edge = g[u].get(i);
                    int v = edge[0];
                    int c = edge[1];
                    if (c + d > dist[v])
                        continue;
 
                    // Path found of same distance
                    if (c + d == dist[v]) {
                        route[v] += route[u];
                    }
 
                    // New path found for lesser distance
                    if (c + d < dist[v]) {
                        dist[v] = c + d;
                        route[v] = route[u];
 
                        // Pushing in priority queue
                        pq.add(new int[] { dist[v], v });
                    }
                }
            }
        }
        System.out.println(route[n]);
    }
 
    public static void main(String[] args)
    {
        // Given Input
        int n = 4;
        int m = 5;
        int[][] edges = { { 1, 4, 5 },
                          { 1, 2, 4 },
                          { 2, 4, 5 },
                          { 1, 3, 2 },
                          { 3, 4, 3 } };
 
        // Function Call
        countDistinctShortestPaths(n, m, edges);
    }
}
 
// This code is contributed by karthik.


Python3




# Python3 program for the above approach
from queue import PriorityQueue
from collections import defaultdict
import sys
 
INF = int(1e9)
MAXN = int(1e5 + 1)
 
# A function to count the number of shortest paths from node 1 to node N
def countDistinctShortestPaths(n, m, edges):
    # Storing the graph using adjacency list
    g = defaultdict(list)
    for i in range(m):
        u, v, c = edges[i]
        g[u].append((v, c))
 
    # Initializing the distance array to a large value
    dist = [INF] * (n + 1)
 
    # Initializing the count array to store the number of shortest paths
    route = [0] * (n + 1)
 
    # Base Cases
    dist[1] = 0
    route[1] = 1
 
    # Initialize a priority queue
    pq = PriorityQueue()
    pq.put((0, 1))
 
    # Loop while priority queue is not empty
    while not pq.empty():
        d, u = pq.get()
 
        # if d is greater than distance of the node
        if d > dist[u]:
            continue
 
        # Traversing all its neighbours
        for v, c in g[u]:
            if c + d > dist[v]:
                continue
 
            # Path found of same distance
            if c + d == dist[v]:
                route[v] += route[u]
 
            # New path found for lesser distance
            if c + d < dist[v]:
                dist[v] = c + d
                route[v] = route[u]
 
                # Pushing in priority queue
                pq.put((dist[v], v))
 
    # Return the number of shortest paths from node 1 to node N
    return route[n]
 
# Driver Code
if __name__ == "__main__":
    # Given Input
    n = 4
    m = 5
    edges = [(1, 4, 5),
             (1, 2, 4),
             (2, 4, 5),
             (1, 3, 2),
             (3, 4, 3)]
 
    # Function Call
    result = countDistinctShortestPaths(n, m, edges)
    print(result)


C#




using System;
using System.Collections.Generic;
 
class ShortestPaths
{
    const int INF = int.MaxValue;
    const int MAXN = 100001;
    static List<List<Tuple<int, int>>> g = new List<List<Tuple<int, int>>>(MAXN);
    static List<int> dist = new List<int>(MAXN);
    static List<int> route = new List<int>(MAXN);
 
    static void CountDistinctShortestPaths(int n, int m, int[,] edges)
    {
        // Storing the graph
        for (int i = 0; i < n + 1; ++i)
        {
            g.Add(new List<Tuple<int, int>>());
            dist.Add(INF);
            route.Add(0);
        }
 
        for (int i = 0; i < m; ++i)
        {
            int u = edges[i, 0];
            int v = edges[i, 1];
            int c = edges[i, 2];
            g[u].Add(new Tuple<int, int>(v, c));
        }
 
        // Initialize a priority queue
        var pq = new SortedSet<Tuple<int, int>>(Comparer<Tuple<int, int>>.Create((x, y) =>
        {
            int compare = x.Item1.CompareTo(y.Item1);
            return compare == 0 ? x.Item2.CompareTo(y.Item2) : compare;
        }));
 
        pq.Add(new Tuple<int, int>(0, 1));
 
        // Base Cases
        dist[1] = 0;
        route[1] = 1;
 
        // Loop while priority queue is not empty
        while (pq.Count > 0)
        {
            var top = pq.Min;
            pq.Remove(top);
 
            int d = top.Item1;
            int u = top.Item2;
 
            // if d is greater than distance of the node
            if (d > dist[u])
                continue;
 
            // Traversing all its neighbours
            foreach (var e in g[u])
            {
                int v = e.Item1;
                int c = e.Item2;
                if (c + d > dist[v])
                    continue;
 
                // Path found of the same distance
                if (c + d == dist[v])
                {
                    route[v] += route[u];
                }
 
                // New path found for lesser distance
                if (c + d < dist[v])
                {
                    dist[v] = c + d;
                    route[v] = route[u];
 
                    // Pushing in priority queue
                    pq.Add(new Tuple<int, int>(dist[v], v));
                }
            }
        }
    }
 
    // Driver Code
    static void Main()
    {
        // Given Input
        int n = 4;
        int m = 5;
        int[,] edges = { { 1, 4, 5 },
                         { 1, 2, 4 },
                         { 2, 4, 5 },
                         { 1, 3, 2 },
                         { 3, 4, 3 } };
 
        // Function Call
        CountDistinctShortestPaths(n, m, edges);
        Console.WriteLine(route[n]);
    }
}


Javascript




// Function to count number of shortest
// paths from node 1 to node N
function countDistinctShortestPaths(n, m, edges) {
    let g = [];
    let dist = [];
    let route = [];
 
    // Storing the graph
    for (let i = 0; i < m; i++) {
        let u = edges[i][0];
        let v = edges[i][1];
        let c = edges[i][2];
        if (!g[u]) {
            g[u] = [];
        }
        g[u].push([v, c]);
    }
 
    // Initializing dis array to a
    // large value
    for (let i = 2; i <= n; i++) {
        dist[i] = Number.MAX_SAFE_INTEGER;
    }
 
    // Base Cases
    dist[1] = 0;
    route[1] = 1;
 
    // Loop while priority queue is
    // not empty
    let pq = [];
    pq.push([0, 1]);
    while (pq.length > 0) {
        let d = pq[0][0];
        let u = pq[0][1];
        pq.shift();
 
        // if d is greater than distance
        // of the node
        if (d > dist[u]) continue;
 
        // Traversing all its neighbours
        if (g[u]) {
            for (let i = 0; i < g[u].length; i++) {
                let v = g[u][i][0];
                let c = g[u][i][1];
                if (c + d > dist[v]) continue;
 
                // Path found of same distance
                if (c + d === dist[v]) {
                    route[v] += route[u];
                }
 
                // New path found for lesser
                // distance
                if (c + d < dist[v]) {
                    dist[v] = c + d;
                    route[v] = route[u];
 
                    // Pushing in priority
                    // queue
                    pq.push([dist[v], v]);
                }
            }
        }
    }
    console.log(route[n]);
}
 
// Given Input
let n = 4;
let m = 5;
let edges = [[1, 4, 5],
    [1, 2, 4],
    [2, 4, 5],
    [1, 3, 2],
    [3, 4, 3]
];
 
// Function Call
countDistinctShortestPaths(n, m, edges);


Output

2

Time Complexity: O(MLogN)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads