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)



Similar Reads

Shortest path with exactly k edges in a directed and weighted graph
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 follow
16 min read
Shortest path with exactly k edges in a directed and weighted graph | Set 2
Given a directed weighted graph and two vertices S and D in it, the task is to find the shortest path from S to D with exactly K edges on the path. If no such path exists, print -1. Examples: Input: N = 3, K = 2, ed = {{{1, 2}, 5}, {{2, 3}, 3}, {{3, 1}, 4}}, S = 1, D = 3 Output: 8 Explanation: The shortest path with two edges will be 1-&gt;2-&gt;3
8 min read
Shortest path from source to destination such that edge weights along path are alternatively increasing and decreasing
Given a connected graph with N vertices and M edges. The task is to find the shortest path from source to the destination vertex such that the difference between adjacent edge weights in the shortest path change from positive to negative and vice versa ( Weight(E1) &gt; Weight(E2) &lt; Weight(E3) .... ). If no such path exists then print -1. Exampl
13 min read
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,
8 min read
Number of paths from source to destination in a directed acyclic graph
Given a Directed Acyclic Graph with n vertices and m edges. The task is to find the number of different paths that exist from a source vertex to destination vertex. Examples: Input: source = 0, destination = 4 Output: 3 Explanation: 0 -&gt; 2 -&gt; 3 -&gt; 4 0 -&gt; 3 -&gt; 4 0 -&gt; 4 Input: source = 0, destination = 1 Output: 1 Explanation: There
22 min read
Number of distinct Shortest Paths from Node 1 to N in a Weighted and Directed Graph
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: 2Explanation: The number of shortest path from node 1 to node 4 is 2, having cost 5. Input: N = 3, M = 2, edge
10 min read
Shortest Path with even number of Edges from Source to Destination
Given an undirected graph G, the task is to find the shortest path of even-length, given 1 as Source Node and N as Destination Node. Path length refers to the number of edges present in a path (not the cost of the path). Examples: Input: N = 5, G is given below: Output: 10 Explanation: All paths from 1(source node) to 5 (destination node) are: 1-
13 min read
Shortest path from a source cell to a destination cell of a Binary Matrix through cells consisting only of 1s
Given a binary matrix mat[][] of dimensions of N * M and pairs of integers src and dest representing source and destination cells respectively, the task is to find the shortest sequence of moves from the given source cell to the destination cell via cells consisting only of 1s. The allowed moves are moving a cell left (L), right (R), up (U), and do
19 min read
Step by step Shortest Path from source node to destination node in a Binary Tree
Given a root of binary tree and two integers startValue and destValue denoting the starting and ending node respectively. The task is to find the shortest path from the start node to the end node and print the path in the form of directions given below. Going from one node to its left child node is indicated by the letter 'L'.Going from one node to
14 min read
Minimum Cost of Simple Path between two nodes in a Directed and Weighted Graph
Given a directed graph, which may contain cycles, where every edge has weight, the task is to find the minimum cost of any simple path from a given source vertex ‘s’ to a given destination vertex ‘t’. Simple Path is the path from one vertex to another such that no vertex is visited more than once. If there is no simple path possible then return INF
10 min read
Article Tags :
Practice Tags :