Open In App

Monotonic shortest path from source to destination in Directed Weighted Graph

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

Given a weighted directed graph with N vertices and M edges, a source src and a destination target, the task is to find the shortest monotonic path (monotonically increasing or decreasing) from the source to the destination. Output -1 if no monotonic path is possible.

Note: All weights are non-negative

Examples:

Input: N = 6, M = 9, src = 1, target = 2
edges = {{1, 3, 1.1}, {1, 5, 2}, {1, 6, 3.3}, {2, 5, 2.7},  
{3, 4, 2}, {3, 5, 1.1}, {4, 2, 2.3}, {5, 6, 2.4}, {6, 2, 3}}

Graph for first example

Graph for first example

Output: 5.4
Explanation: There are three monotonic paths in the graph 
that originate from vertex 1, which are 1 – 6 – 2 because it is strictly increasing,  
and 1 – 3 – 4 – 2, and 1 – 5 – 6 – 2 since both are strictly decreasing. 
The shortest one of these paths is 1 – 3 – 4 – 2,  
which has a sum of weights equal to 1.1 + 2 + 2.3 = 5.4,  
So the output is 5.4.

Input: N = 5, M = 5, src = 1, target = 5
edges = {{1, 2, 2.3}, {1, 3, 3.1}, {2, 3, 3.7}, {3, 4, 1.9}, {4, 5, 2.1}}

Graph for second example

Graph for second example

Output: -1
Explanation: No monotonic path exists from vertex 1 to vertex 5.

Approach: To solve the problem follow the below idea:

Run Dijkstra’s algorithm twice: one for increasing shortest paths and another for decreasing shortest paths, and take the shorter path of the two results. 

Follow the given steps to solve the problem:

  • Run Dijkstra’s algorithm twice for both increasing and decreasing paths.
    • While doing Dijkstra’s for decreasing shortest paths: 
      • Only update the shortest path to a vertex v from vertex u if the weight of the edge from u to v is less than the edge on the shortest path directed towards u
    • Similarly for the increasing shortest paths: 
      • Only update the shortest path to a vertex v from u, if the edge from u to v is greater than the edge on the shortest path directed towards u.
  • If the destination vertex has not yet been reached, then no valid shortest path exists. 
  • If both passes of Dijkstra’s on increasing and decreasing shortest paths result in no valid paths, then return -1.

Below is the implementation of the above approach.

C++




#include <bits/stdc++.h>
#include <limits>
#include <queue>
#include <vector>
 
using namespace std;
 
// Represents a vertex in the graph
class Vertex {
public:
    int id;
    vector<int> adjList;
    vector<double> adjWeights;
 
    // A constructor which accepts the id of the vertex
    Vertex(int num)
        : id(num)
    {
    }
};
 
// Finds the monotonic shortest path using Dijkstra's
// algorithm
double shortestPath(vector<Vertex>& vertices, int src,
                    int destination)
{
    int N = vertices.size() - 1;
 
    // Stores distance from src and edge on the shortest
    // path from src
    vector<double> distTo(N + 1,
                          numeric_limits<double>::max());
    vector<double> edgeTo(N + 1,
                          numeric_limits<double>::max());
 
    // Set initial distance from src to the highest value
    for (int i = 1; i <= N; i++) {
        distTo[i] = numeric_limits<double>::max();
    }
 
    // Monotonic decreasing pass of Dijkstra's
    distTo[src] = 0.0;
    edgeTo[src] = numeric_limits<double>::max();
 
    priority_queue<pair<double, int>,
                   vector<pair<double, int> >,
                   greater<pair<double, int> > >
        pq;
    pq.push(make_pair(0.0, src));
 
    while (!pq.empty()) {
        // Take the vertex with the closest current distance
        // from src
        pair<double, int> top = pq.top();
        pq.pop();
        int closest = top.second;
 
        for (int i = 0;
             i < vertices[closest].adjList.size(); i++) {
            int neighbor = vertices[closest].adjList[i];
            double weight = vertices[closest].adjWeights[i];
 
            // Checks if the edges are decreasing and
            // whether the current directed edge will create
            // a shorter path
            if (weight < edgeTo[closest]
                && distTo[closest] + weight
                       < distTo[neighbor]) {
                edgeTo[neighbor] = weight;
                distTo[neighbor] = distTo[closest] + weight;
                pq.push(
                    make_pair(distTo[neighbor], neighbor));
            }
        }
    }
 
    // Store the result of the first pass of Dijkstra's
    double firstPass = distTo[destination];
 
    // Monotonic increasing pass of Dijkstra's
    for (int i = 1; i <= N; i++) {
        distTo[i] = numeric_limits<double>::max();
    }
 
    distTo[src] = 0.0;
    edgeTo[src] = 0.0;
 
    pq.push(make_pair(0.0, src));
 
    while (!pq.empty()) {
        // Take the vertex with the closest current distance
        // from src
        pair<double, int> top = pq.top();
        pq.pop();
        int closest = top.second;
 
        for (int i = 0;
             i < vertices[closest].adjList.size(); i++) {
            int neighbor = vertices[closest].adjList[i];
            double weight = vertices[closest].adjWeights[i];
 
            // Checks if the edges are increasing and
            // whether the current directed edge will create
            // a shorter path
            if (weight > edgeTo[closest]
                && distTo[closest] + weight
                       < distTo[neighbor]) {
                edgeTo[neighbor] = weight;
                distTo[neighbor] = distTo[closest] + weight;
                pq.push(
                    make_pair(distTo[neighbor], neighbor));
            }
        }
    }
 
    // Store the result of the second pass of Dijkstras
    double secondPass = distTo[destination];
 
    if (firstPass == DBL_MAX && secondPass == DBL_MAX)
        return -1;
 
    return min(firstPass, secondPass);
}
 
// Driver Code
int main()
{
    int N = 6, M = 9, src, target;
 
    // Create N vertices, numbered 1 to N
    vector<Vertex> vertices(N + 1, Vertex(0));
 
    for (int i = 1; i <= N; i++) {
        vertices[i] = Vertex(i);
    }
 
    // Add M edges to the graph
    vertices[1].adjList.push_back(3);
    vertices[1].adjWeights.push_back(1.1);
 
    vertices[1].adjList.push_back(5);
    vertices[1].adjWeights.push_back(2.0);
 
    vertices[1].adjList.push_back(6);
    vertices[1].adjWeights.push_back(3.3);
 
    vertices[2].adjList.push_back(5);
    vertices[2].adjWeights.push_back(2.7);
 
    vertices[3].adjList.push_back(4);
    vertices[3].adjWeights.push_back(2.0);
 
    vertices[3].adjList.push_back(5);
    vertices[3].adjWeights.push_back(1.1);
 
    vertices[4].adjList.push_back(2);
    vertices[4].adjWeights.push_back(2.3);
 
    vertices[5].adjList.push_back(6);
    vertices[5].adjWeights.push_back(2.4);
 
    vertices[6].adjList.push_back(2);
    vertices[6].adjWeights.push_back(3.0);
 
    // src and destination vertices
    src = 1;
    target = 2;
 
    double shortest = shortestPath(vertices, src, target);
 
    cout << shortest << endl;
 
    return 0;
}


Java




import java.io.*;
import java.util.*;
 
// Finds the monotonic shortest path
// using Dijkstra's algorithm
public class Main {
    public static void main(String[] args)
    {
        int N = 6;
        int M = 9;
 
        // Create an array of vertices
        Vertex[] vertices = new Vertex[N + 1];
 
        // Create instances of each vertex from 1 to N
        for (int i = 1; i <= N; i++)
            vertices[i] = new Vertex(i);
 
        vertices[1].adjList.add(3);
        vertices[1].adjWeights.add(1.1);
 
        vertices[1].adjList.add(5);
        vertices[1].adjWeights.add(2.0);
 
        vertices[1].adjList.add(6);
        vertices[1].adjWeights.add(3.3);
 
        vertices[2].adjList.add(5);
        vertices[2].adjWeights.add(2.7);
 
        vertices[3].adjList.add(4);
        vertices[3].adjWeights.add(2.0);
 
        vertices[3].adjList.add(5);
        vertices[3].adjWeights.add(1.1);
 
        vertices[4].adjList.add(2);
        vertices[4].adjWeights.add(2.3);
 
        vertices[5].adjList.add(6);
        vertices[5].adjWeights.add(2.4);
 
        vertices[6].adjList.add(2);
        vertices[6].adjWeights.add(3.0);
 
        // src and destination vertices
        int src = 1;
        int target = 2;
        System.out.println(
            shortestPath(vertices, N, src, target));
    }
 
    public static double shortestPath(Vertex vertices[],
                                      int N, int src,
                                      int destination)
    {
        // Stores distance from src and edge
        // on the shortest path from src
        double[] distTo = new double[N + 1];
        double[] edgeTo = new double[N + 1];
 
        // Set initial distance from src
        // to the highest value
        for (int i = 1; i <= N; i++)
            distTo[i] = Double.MAX_VALUE;
 
        // Monotonic decreasing pass of dijkstras
        distTo[src] = 0.0;
        edgeTo[src] = Double.MAX_VALUE;
 
        PriorityQueue<Vertex> pq
            = new PriorityQueue<Vertex>(
                new Comparator<Vertex>() {
                    public int compare(Vertex a, Vertex b)
                    {
                        return Double.compare(distTo[a.id],
                                              distTo[b.id]);
                    }
                });
 
        // Add the initial src vertex
        // into the priority queue
        pq.add(vertices[src]);
 
        while (!pq.isEmpty()) {
 
            // Take the vertex with the closest
            // current distance from src
            Vertex closest = pq.remove();
 
            for (int i = 0; i < closest.adjList.size();
                 i++) {
 
                // Checks if the edges are decreasing and
                // whether the current directed edge will
                // create a shorter path
                if (closest.adjWeights.get(i)
                        < edgeTo[closest.id]
                    && distTo[closest.id]
                               + closest.adjWeights.get(i)
                           < distTo[closest.adjList.get(
                               i)]) {
                    edgeTo[closest.adjList.get(i)]
                        = closest.adjWeights.get(i);
                    distTo[closest.adjList.get(i)]
                        = closest.adjWeights.get(i)
                          + distTo[closest.id];
                    pq.add(
                        vertices[closest.adjList.get(i)]);
                }
            }
        }
 
        // Store the result of the first pass of dijkstras
        double firstPass = distTo[destination];
 
        // Monotonic increasing pass of dijkstras
        for (int i = 1; i <= N; i++)
            distTo[i] = Double.MAX_VALUE;
        distTo[src] = 0.0;
        edgeTo[src] = 0.0;
 
        // Add the initial src vertex
        // into the priority queue
        pq.add(vertices[src]);
 
        while (!pq.isEmpty()) {
 
            // Take the vertex with the closest current
            // distance from src
            Vertex closest = pq.remove();
 
            for (int i = 0; i < closest.adjList.size();
                 i++) {
 
                // Checks if the edges are increasing and
                // whether the current directed edge will
                // create a shorter path
                if (closest.adjWeights.get(i)
                        > edgeTo[closest.id]
                    && distTo[closest.id]
                               + closest.adjWeights.get(i)
                           < distTo[closest.adjList.get(
                               i)]) {
                    edgeTo[closest.adjList.get(i)]
                        = closest.adjWeights.get(i);
                    distTo[closest.adjList.get(i)]
                        = closest.adjWeights.get(i)
                          + distTo[closest.id];
                    pq.add(
                        vertices[closest.adjList.get(i)]);
                }
            }
        }
 
        // Store the result of the second pass of Dijkstras
        double secondPass = distTo[destination];
 
        if (firstPass == Double.MAX_VALUE
            && secondPass == Double.MAX_VALUE)
            return -1;
        return Math.min(firstPass, secondPass);
    }
}
 
// Represents a vertex in the graph
// id stores the vertex number of the vertex instance
// adjList stores the id's of adjacent vertices
// adjWeights stores the weights of adjacent vertices with
// the same indexing as adjList
class Vertex {
    int id;
    ArrayList<Integer> adjList;
    ArrayList<Double> adjWeights;
 
    // A constructor which accepts
    // the id of the vertex
    public Vertex(int num)
    {
        id = num;
        adjList = new ArrayList<Integer>();
        adjWeights = new ArrayList<Double>();
    }
}


Python3




import heapq
 
class Vertex:
    def __init__(self, num):
        self.id = num
        self.adjList = []
        self.adjWeights = []
 
def shortestPath(vertices, N, src, destination):
    # Stores distance from src and edge on the shortest path from src
    distTo = [float('inf')] * (N + 1)
    edgeTo = [0.0] * (N + 1)
 
    # Monotonic decreasing pass of Dijkstra's
    distTo[src] = 0.0
    edgeTo[src] = float('inf')
 
    pq = []
    heapq.heappush(pq, (distTo[src], vertices[src]))
 
    while pq:
        # Take the vertex with the closest current distance from src
        dist, closest = heapq.heappop(pq)
 
        for i in range(len(closest.adjList)):
            # Checks if the edges are decreasing and whether the current directed edge will create a shorter path
            if (closest.adjWeights[i] < edgeTo[closest.id] and
                distTo[closest.id] + closest.adjWeights[i] < distTo[closest.adjList[i]]):
 
                edgeTo[closest.adjList[i]] = closest.adjWeights[i]
                distTo[closest.adjList[i]] = closest.adjWeights[i] + distTo[closest.id]
                heapq.heappush(pq, (distTo[closest.adjList[i]], vertices[closest.adjList[i]]))
 
    # Store the result of the first pass of Dijkstra's
    firstPass = distTo[destination]
 
    # Monotonic increasing pass of Dijkstra's
    distTo = [float('inf')] * (N + 1)
    distTo[src] = 0.0
    edgeTo[src] = 0.0
 
    pq = []
    heapq.heappush(pq, (distTo[src], vertices[src]))
 
    while pq:
        # Take the vertex with the closest current distance from src
        dist, closest = heapq.heappop(pq)
 
        for i in range(len(closest.adjList)):
            # Checks if the edges are increasing and whether the current directed edge will create a shorter path
            if (closest.adjWeights[i] > edgeTo[closest.id] and
                distTo[closest.id] + closest.adjWeights[i] < distTo[closest.adjList[i]]):
 
                edgeTo[closest.adjList[i]] = closest.adjWeights[i]
                distTo[closest.adjList[i]] = closest.adjWeights[i] + distTo[closest.id]
                heapq.heappush(pq, (distTo[closest.adjList[i]], vertices[closest.adjList[i]]))
 
    # Store the result of the second pass of Dijkstra's
    secondPass = distTo[destination]
 
    if firstPass == float('inf') and secondPass == float('inf'):
        return -1
    return min(firstPass, secondPass)
 
if __name__ == "__main__":
    N = 6
 
    # Create an array of vertices
    vertices = [None] * (N + 1)
 
    # Create instances of each vertex from 1 to N
    for i in range(1, N + 1):
        vertices[i] = Vertex(i)
 
    vertices[1].adjList.append(3)
    vertices[1].adjWeights.append(1.1)
 
    vertices[1].adjList.append(5)
    vertices[1].adjWeights.append(2.0)
 
    vertices[1].adjList.append(6)
    vertices[1].adjWeights.append(3.3)
 
    vertices[2].adjList.append(5)
    vertices[2].adjWeights.append(2.7)
 
    vertices[3].adjList.append(4)
    vertices[3].adjWeights.append(2.0)
 
    vertices[3].adjList.append(5)
    vertices[3].adjWeights.append(1.1)
 
    vertices[4].adjList.append(2)
    vertices[4].adjWeights.append(2.3)
 
    vertices[5].adjList.append(6)
    vertices[5].adjWeights.append(2.4)
 
    vertices[6].adjList.append(2)
    vertices[6].adjWeights.append(3.0)
 
    # src and destination vertices
    src = 1
    target = 2
    print(shortestPath(vertices, N, src, target))


C#




using System;
using System.Collections.Generic;
 
class Vertex
{
    public int Id { get; }
    public List<int> AdjList { get; } = new List<int>();
    public List<double> AdjWeights { get; } = new List<double>();
 
    public Vertex(int id)
    {
        Id = id;
    }
}
 
class Program
{
    static double ShortestPath(Vertex[] vertices, int N, int src, int destination)
    {
        double[] distTo = new double[N + 1];
        double[] edgeTo = new double[N + 1];
 
        for (int i = 1; i <= N; i++)
            distTo[i] = double.PositiveInfinity;
 
        distTo[src] = 0.0;
        edgeTo[src] = double.PositiveInfinity;
 
        PriorityQueue<Tuple<double, Vertex>> pq = new PriorityQueue<Tuple<double, Vertex>>(
            Comparer<Tuple<double, Vertex>>.Create((a, b) => a.Item1.CompareTo(b.Item1)));
 
        pq.Enqueue(Tuple.Create(distTo[src], vertices[src]));
 
        while (!pq.IsEmpty)
        {
            var pair = pq.Dequeue();
            double dist = pair.Item1;
            Vertex closest = pair.Item2;
 
            for (int i = 0; i < closest.AdjList.Count; i++)
            {
                if (closest.AdjWeights[i] < edgeTo[closest.Id] &&
                    distTo[closest.Id] + closest.AdjWeights[i] < distTo[closest.AdjList[i]])
                {
                    edgeTo[closest.AdjList[i]] = closest.AdjWeights[i];
                    distTo[closest.AdjList[i]] = closest.AdjWeights[i] + distTo[closest.Id];
                    pq.Enqueue(Tuple.Create(distTo[closest.AdjList[i]],
                                            vertices[closest.AdjList[i]]));
                }
            }
        }
 
        double firstPass = distTo[destination];
 
        for (int i = 1; i <= N; i++)
            distTo[i] = double.PositiveInfinity;
 
        distTo[src] = 0.0;
        edgeTo[src] = 0.0;
 
        pq.Enqueue(Tuple.Create(distTo[src], vertices[src]));
 
        while (!pq.IsEmpty)
        {
            var pair = pq.Dequeue();
            double dist = pair.Item1;
            Vertex closest = pair.Item2;
 
            for (int i = 0; i < closest.AdjList.Count; i++)
            {
                if (closest.AdjWeights[i] > edgeTo[closest.Id] &&
                    distTo[closest.Id] + closest.AdjWeights[i] < distTo[closest.AdjList[i]])
                {
                    edgeTo[closest.AdjList[i]] = closest.AdjWeights[i];
                    distTo[closest.AdjList[i]] = closest.AdjWeights[i] + distTo[closest.Id];
                    pq.Enqueue(Tuple.Create(distTo[closest.AdjList[i]],
                                            vertices[closest.AdjList[i]]));
                }
            }
        }
 
        double secondPass = distTo[destination];
 
        if (firstPass == double.PositiveInfinity && secondPass == double.PositiveInfinity)
            return -1;
        return Math.Min(firstPass, secondPass);
    }
 
    static void Main(string[] args)
    {
        int N = 6;
 
        Vertex[] vertices = new Vertex[N + 1];
 
        for (int i = 1; i <= N; i++)
            vertices[i] = new Vertex(i);
 
        vertices[1].AdjList.Add(3);
        vertices[1].AdjWeights.Add(1.1);
 
        vertices[1].AdjList.Add(5);
        vertices[1].AdjWeights.Add(2.0);
 
        vertices[1].AdjList.Add(6);
        vertices[1].AdjWeights.Add(3.3);
 
        vertices[2].AdjList.Add(5);
        vertices[2].AdjWeights.Add(2.7);
 
        vertices[3].AdjList.Add(4);
        vertices[3].AdjWeights.Add(2.0);
 
        vertices[3].AdjList.Add(5);
        vertices[3].AdjWeights.Add(1.1);
 
        vertices[4].AdjList.Add(2);
        vertices[4].AdjWeights.Add(2.3);
 
        vertices[5].AdjList.Add(6);
        vertices[5].AdjWeights.Add(2.4);
 
        vertices[6].AdjList.Add(2);
        vertices[6].AdjWeights.Add(3.0);
 
        int src = 1;
        int target = 2;
        Console.WriteLine(ShortestPath(vertices, N, src, target));
    }
}
 
class PriorityQueue<T>
{
    private List<T> list = new List<T>();
    private readonly IComparer<T> comparer;
 
    public PriorityQueue(IComparer<T> comparer)
    {
        this.comparer = comparer;
    }
 
    public void Enqueue(T item)
    {
        list.Add(item);
        int childIndex = list.Count - 1;
 
        while (childIndex > 0)
        {
            int parentIndex = (childIndex - 1) / 2;
            if (comparer.Compare(list[childIndex], list[parentIndex]) >= 0)
                break;
 
            T tmp = list[childIndex];
            list[childIndex] = list[parentIndex];
            list[parentIndex] = tmp;
 
            childIndex = parentIndex;
        }
    }
 
    public T Dequeue()
    {
        int lastIndex = list.Count - 1;
        T frontItem = list[0];
        list[0] = list[lastIndex];
        list.RemoveAt(lastIndex);
 
        lastIndex--;
        int parentIndex = 0;
 
        while (true)
        {
            int leftChildIndex = 2 * parentIndex + 1;
            int rightChildIndex = 2 * parentIndex + 2;
 
            if (leftChildIndex > lastIndex)
                break;
 
            int childIndex = leftChildIndex;
            if (rightChildIndex <= lastIndex &&
                comparer.Compare(list[leftChildIndex], list[rightChildIndex]) > 0)
                childIndex = rightChildIndex;
 
            if (comparer.Compare(list[parentIndex], list[childIndex]) <= 0)
                break;
 
            T tmp = list[parentIndex];
            list[parentIndex] = list[childIndex];
            list[childIndex] = tmp;
 
            parentIndex = childIndex;
        }
 
        return frontItem;
    }
 
    public bool IsEmpty
    {
        get { return list.Count == 0; }
    }
}


Javascript




// Represents a vertex in the graph
class Vertex {
    constructor(num) {
        this.id = num;
        this.adjList = [];
        this.adjWeights = [];
    }
}
 
class PriorityQueue {
    constructor() {
        this.queue = [];
    }
 
    push(item, priority) {
        this.queue.push({ item, priority });
        this.queue.sort((a, b) => a.priority - b.priority);
    }
 
    pop() {
        if (this.isEmpty()) return null;
        return this.queue.shift().item;
    }
 
    isEmpty() {
        return this.queue.length === 0;
    }
}
 
// Finds the monotonic shortest path using Dijkstra's
// algorithm
function shortestPath(vertices, src, destination) {
    const N = vertices.length - 1;
 
    // Stores distance from src and edge on the shortest
    // path from src
    const distTo = new Array(N + 1).fill(Number.POSITIVE_INFINITY);
    const edgeTo = new Array(N + 1).fill(Number.POSITIVE_INFINITY);
     
    // Set initial distance from src to the highest value
    for (let i = 1; i <= N; i++) {
        distTo[i] = Number.POSITIVE_INFINITY;
    }
 
    // Monotonic decreasing pass of Dijkstra's
    distTo[src] = 0.0;
    edgeTo[src] = Number.POSITIVE_INFINITY;
 
    const pq = new PriorityQueue();
    pq.push(src, 0.0);
 
    while (!pq.isEmpty()) {
        // Take the vertex with the closest current distance
        // from src
        const closest = pq.pop();
 
        for (let i = 0; i < vertices[closest].adjList.length; i++) {
            const neighbor = vertices[closest].adjList[i];
            const weight = vertices[closest].adjWeights[i];
 
            // Checks if the edges are decreasing and
            // whether the current directed edge will create
            // a shorter path
            if (weight < edgeTo[closest] && distTo[closest] + weight < distTo[neighbor]) {
                edgeTo[neighbor] = weight;
                distTo[neighbor] = distTo[closest] + weight;
                pq.push(neighbor, distTo[neighbor]);
            }
        }
    }
 
    // Store the result of the first pass of Dijkstra's
    const firstPass = distTo[destination];
 
    // Monotonic increasing pass of Dijkstra's
    for (let i = 1; i <= N; i++) {
        distTo[i] = Number.POSITIVE_INFINITY;
    }
 
    distTo[src] = 0.0;
    edgeTo[src] = 0.0;
 
    pq.push(src, 0.0);
 
    while (!pq.isEmpty()) {
        // Take the vertex with the closest current distance
        // from src
        const closest = pq.pop();
 
        for (let i = 0; i < vertices[closest].adjList.length; i++) {
            const neighbor = vertices[closest].adjList[i];
            const weight = vertices[closest].adjWeights[i];
 
            // Checks if the edges are increasing and
            // whether the current directed edge will create
            // a shorter path
            if (weight > edgeTo[closest] && distTo[closest] + weight < distTo[neighbor]) {
                edgeTo[neighbor] = weight;
                distTo[neighbor] = distTo[closest] + weight;
                pq.push(neighbor, distTo[neighbor]);
            }
        }
    }
 
    // Store the result of the second pass of Dijkstras
    const secondPass = distTo[destination];
 
    if (firstPass === Number.POSITIVE_INFINITY && secondPass === Number.POSITIVE_INFINITY) {
        return -1;
    }
 
    return Math.min(firstPass, secondPass);
}
 
// Driver Code
const N = 6;
const src = 1;
const target = 2;
 
// Create N vertices, numbered 1 to N
const vertices = Array.from({ length: N + 1 }, (_, i) => new Vertex(i));
 
// Add M edges to the graph
vertices[1].adjList.push(3);
vertices[1].adjWeights.push(1.1);
 
vertices[1].adjList.push(5);
vertices[1].adjWeights.push(2.0);
 
vertices[1].adjList.push(6);
vertices[1].adjWeights.push(3.3);
 
vertices[2].adjList.push(5);
vertices[2].adjWeights.push(2.7);
 
vertices[3].adjList.push(4);
vertices[3].adjWeights.push(2.0);
 
vertices[3].adjList.push(5);
vertices[3].adjWeights.push(1.1);
 
vertices[4].adjList.push(2);
vertices[4].adjWeights.push(2.3);
 
vertices[5].adjList.push(6);
vertices[5].adjWeights.push(2.4);
 
vertices[6].adjList.push(2);
vertices[6].adjWeights.push(3.0);
 
const shortest = shortestPath(vertices, src, target);
console.log(shortest);


Output

5.4







Time Complexity: O(N log(N) + M)
Auxiliary Space: O(N)



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

Similar Reads