Dijkstra's Shortest Path Algorithm using priority_queue of STL (original) (raw)

Given a graph and a source vertex in graph, find shortest paths from source to all vertices in the given graph.

Input : Source = 0
Output :
Vertex Distance from Source
0 0
1 4
2 12
3 19
4 21
5 11
6 9
7 8
8 14

We have discussed Dijkstra’s shortest Path implementations.

The second implementation is time complexity wise better but is really complex as we have implemented our own priority queue. The Third implementation is simpler as it uses STL. The issue with third implementation is, it uses set which in turn uses Self-Balancing Binary Search Trees. For Dijkstra's algorithm, it is always recommended to use heap (or priority queue) as the required operations (extract minimum and decrease key) match with speciality of heap (or priority queue). However, the problem is, priority_queue doesn't support decrease key. To resolve this problem, do not update a key, but insert one more copy of it. So we allow multiple instances of same vertex in priority queue. This approach doesn't require decrease key operation and has below important properties.

Below is algorithm based on above idea.

  1. Initialize distances of all vertices as infinite.

  2. Create an empty **priority_**queue **pq. Every item
    of pq is a pair (weight, vertex). Weight (or
    distance) is used as first item of pair
    as first item is by default used to compare
    two pairs

  3. Insert source vertex into pq and make its
    distance as 0.

  4. While either pq doesn't become empty
    a) Extract minimum distance vertex from pq.
    Let the extracted vertex be u.
    b) Loop through all adjacent of u and do
    following for every vertex v.
    // If there is a shorter path to v
    // through u.
    If dist[v] > dist[u] + weight(u, v)
    (i) Update distance of v, i.e., do
    dist[v] = dist[u] + weight(u, v)
    (ii) Insert v into the pq (Even if v is
    already there)

  5. Print distance array dist[] to print all shortest
    paths.

Below implementation of above idea:

C++ `

// Program to find Dijkstra's shortest path using // priority_queue in STL #include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f

// iPair ==> Integer Pair typedef pair<int, int> iPair;

// This class represents a directed graph using // adjacency list representation class Graph { int V; // No. of vertices

// In a weighted graph, we need to store vertex
// and weight pair for every edge
list<pair<int, int> >* adj;

public: Graph(int V); // Constructor

// function to add an edge to graph
void addEdge(int u, int v, int w);

// prints shortest path from s
void shortestPath(int s);

};

// Allocates memory for adjacency list Graph::Graph(int V) { this->V = V; adj = new list[V]; }

void Graph::addEdge(int u, int v, int w) { adj[u].push_back(make_pair(v, w)); adj[v].push_back(make_pair(u, w)); }

// Prints shortest paths from src to all other vertices void Graph::shortestPath(int src) { // Create a priority queue to store vertices that // are being preprocessed. This is weird syntax in C++. // Refer below link for details of this syntax // https://www.geeksforgeeks.org/implement-min-heap-using-stl/ priority_queue<iPair, vector, greater > pq;

// Create a vector for distances and initialize all
// distances as infinite (INF)
vector<int> dist(V, INF);

// Insert source itself in priority queue and initialize
// its distance as 0.
pq.push(make_pair(0, src));
dist[src] = 0;

/* Looping till priority queue becomes empty (or all
distances are not finalized) */
while (!pq.empty()) {
    // The first vertex in pair is the minimum distance
    // vertex, extract it from priority queue.
    // vertex label is stored in second of pair (it
    // has to be done this way to keep the vertices
    // sorted distance (distance must be first item
    // in pair)
    int u = pq.top().second;
    pq.pop();

    // 'i' is used to get all adjacent vertices of a
    // vertex
    list<pair<int, int> >::iterator i;
    for (i = adj[u].begin(); i != adj[u].end(); ++i) {
        // Get vertex label and weight of current
        // adjacent of u.
        int v = (*i).first;
        int weight = (*i).second;

        // If there is shorted path to v through u.
        if (dist[v] > dist[u] + weight) {
            // Updating distance of v
            dist[v] = dist[u] + weight;
            pq.push(make_pair(dist[v], v));
        }
    }
}

// Print shortest distances stored in dist[]
printf("Vertex Distance from Source\n");
for (int i = 0; i < V; ++i)
    printf("%d \t\t %d\n", i, dist[i]);

}

// Driver program to test methods of graph class int main() { // create the graph given in above figure int V = 9; Graph g(V);

// making above shown graph
g.addEdge(0, 1, 4);
g.addEdge(0, 7, 8);
g.addEdge(1, 2, 8);
g.addEdge(1, 7, 11);
g.addEdge(2, 3, 7);
g.addEdge(2, 8, 2);
g.addEdge(2, 5, 4);
g.addEdge(3, 4, 9);
g.addEdge(3, 5, 14);
g.addEdge(4, 5, 10);
g.addEdge(5, 6, 2);
g.addEdge(6, 7, 1);
g.addEdge(6, 8, 6);
g.addEdge(7, 8, 7);

g.shortestPath(0);

return 0;

}

Java

// Java program for the above approach import java.util.*;

// Class to represent a graph and implement Dijkstra's // shortest path algorithm class Graph { private int V; // Number of vertices private List<int[]>[] adj; // Adjacency list to store // graph edges

// Inner class to represent a pair of vertex and its
// weight
class iPair implements Comparable<iPair> {
    int vertex, weight;

    iPair(int v, int w)
    {
        vertex = v;
        weight = w;
    }

    // Comparison method for priority queue
    public int compareTo(iPair other)
    {
        return Integer.compare(this.weight,
                               other.weight);
    }
}

// Constructor to initialize the graph
Graph(int V)
{
    this.V = V;
    adj = new ArrayList[V];
    for (int i = 0; i < V; ++i)
        adj[i] = new ArrayList<>();
}

// Method to add an edge to the graph
void addEdge(int u, int v, int w)
{
    adj[u].add(new int[] { v, w });
    adj[v].add(new int[] { u, w });
}

// Method to find the shortest paths from source vertex
// to all other vertices
void shortestPath(int src)
{
    PriorityQueue<iPair> pq = new PriorityQueue<>();
    int[] dist = new int[V];
    Arrays.fill(dist, Integer.MAX_VALUE);

    pq.add(new iPair(src, 0));
    dist[src] = 0;

    // Dijkstra's algorithm
    while (!pq.isEmpty()) {
        int u = pq.poll().vertex;

        for (int[] neighbor : adj[u]) {
            int v = neighbor[0];
            int weight = neighbor[1];

            // Relaxation step
            if (dist[v] > dist[u] + weight) {
                dist[v] = dist[u] + weight;
                pq.add(new iPair(v, dist[v]));
            }
        }
    }

    // Print shortest distances from source
    System.out.println("Vertex Distance from Source");
    for (int i = 0; i < V; ++i)
        System.out.println(i + "\t\t" + dist[i]);
}

}

// Main class containing the main method to test the graph // and Dijkstra's algorithm public class GFG { public static void main(String[] args) { int V = 9; Graph g = new Graph(V);

    // Adding edges to create the graph
    g.addEdge(0, 1, 4);
    g.addEdge(0, 7, 8);
    g.addEdge(1, 2, 8);
    g.addEdge(1, 7, 11);
    g.addEdge(2, 3, 7);
    g.addEdge(2, 8, 2);
    g.addEdge(2, 5, 4);
    g.addEdge(3, 4, 9);
    g.addEdge(3, 5, 14);
    g.addEdge(4, 5, 10);
    g.addEdge(5, 6, 2);
    g.addEdge(6, 7, 1);
    g.addEdge(6, 8, 6);
    g.addEdge(7, 8, 7);

    // Finding and printing the shortest paths from
    // source vertex 0
    g.shortestPath(0);
}

}

// This code is contributed by Susobhan Akhuli

Python

Python program for the above approach

import heapq

This class represents a directed graph using

adjacency list representation

class Graph: def init(self, V): self.V = V # No. of vertices self.adj = [[] for _ in range(V)] # In a weighted graph, store vertex and weight pair for every edge

# Function to add an edge to the graph
def add_edge(self, u, v, w):
    self.adj[u].append((v, w))
    self.adj[v].append((u, w))

# Prints shortest paths from src to all other vertices
def shortest_path(self, src):
    # Create a priority queue to store vertices that
    # are being preprocessed.
    pq = [(0, src)]  # The first element of the tuple is the distance, and the second is the vertex label

    # Create a list for distances and initialize all
    # distances as infinite (INF)
    dist = [float('inf')] * self.V
    dist[src] = 0

    # Looping until the priority queue becomes empty
    while pq:
        # The first element in the tuple is the minimum distance vertex
        # Extract it from the priority queue
        current_dist, u = heapq.heappop(pq)

        # Iterate over all adjacent vertices of a vertex
        for v, weight in self.adj[u]:
            # If there is a shorter path to v through u
            if dist[v] > dist[u] + weight:
                # Update the distance of v
                dist[v] = dist[u] + weight
                heapq.heappush(pq, (dist[v], v))

    # Print shortest distances
    print("Vertex Distance from Source")
    for i in range(self.V):
        print(f"{i}\t\t{dist[i]}")

Driver program to test methods of the graph class

if name == "main": # Create the graph given in the above figure V = 9 g = Graph(V)

# Making the above-shown graph
g.add_edge(0, 1, 4)
g.add_edge(0, 7, 8)
g.add_edge(1, 2, 8)
g.add_edge(1, 7, 11)
g.add_edge(2, 3, 7)
g.add_edge(2, 8, 2)
g.add_edge(2, 5, 4)
g.add_edge(3, 4, 9)
g.add_edge(3, 5, 14)
g.add_edge(4, 5, 10)
g.add_edge(5, 6, 2)
g.add_edge(6, 7, 1)
g.add_edge(6, 8, 6)
g.add_edge(7, 8, 7)

g.shortest_path(0)

This code is contributed by Susobhan Akhuli

C#

// C# program for the above approach using System; using System.Collections.Generic;

// Class to represent a graph class Graph { private int V; // No. of vertices private List<Tuple<int, int>>[] adj;

// iPair ==> Integer Pair
public Graph(int V)
{
    this.V = V;
    adj = new List<Tuple<int, int>>[V];
    for (int i = 0; i < V; ++i)
        adj[i] = new List<Tuple<int, int>>();
}

// function to add an edge to graph
public void addEdge(int u, int v, int w)
{
    adj[u].Add(new Tuple<int, int>(v, w));
    adj[v].Add(new Tuple<int, int>(u, w));
}

// prints shortest paths from src
public void shortestPath(int src)
{
    // Create a sorted set to store vertices that
    // are being preprocessed.
    SortedSet<Tuple<int, int>> pq = new SortedSet<Tuple<int, int>>(Comparer<Tuple<int, int>>.Create((a, b) =>
    {
        int cmp = a.Item1.CompareTo(b.Item1);
        return cmp == 0 ? a.Item2.CompareTo(b.Item2) : cmp;
    }));

    // Create a vector for distances and initialize all
    // distances as infinite (INF)
    int[] dist = new int[V];
    for (int i = 0; i < V; ++i)
        dist[i] = int.MaxValue;

    // Insert source itself in the sorted set and initialize
    // its distance as 0.
    pq.Add(new Tuple<int, int>(0, src));
    dist[src] = 0;

    /* Looping till the sorted set becomes empty (or all
    distances are not finalized) */
    while (pq.Count > 0)
    {
        // The first vertex in tuple is the minimum distance
        // vertex, extract it from the sorted set.
        // vertex label is stored in the second element of the tuple.
        // (it has to be done this way to keep the vertices
        // sorted by distance, where distance must be the first item
        // in the tuple)
        int u = pq.Min.Item2;
        pq.Remove(pq.Min);

        // 'i' is used to get all adjacent vertices of a
        // vertex
        foreach (var i in adj[u])
        {
            // Get vertex label and weight of the current
            // adjacent vertex of u.
            int v = i.Item1;
            int weight = i.Item2;

            // If there is a shorter path to v through u.
            if (dist[v] > dist[u] + weight)
            {
                // Updating distance of v
                pq.Add(new Tuple<int, int>(dist[u] + weight, v));
                dist[v] = dist[u] + weight;
            }
        }
    }

    // Print shortest distances stored in dist[]
    Console.WriteLine("Vertex Distance from Source");
    for (int i = 0; i < V; ++i)
        Console.WriteLine(i + "\t\t" + dist[i]);
}

}

// Driver program to test methods of the graph class class GFG { static void Main() { // Create the graph given in the above figure int V = 9; Graph g = new Graph(V);

    // making above shown graph
    g.addEdge(0, 1, 4);
    g.addEdge(0, 7, 8);
    g.addEdge(1, 2, 8);
    g.addEdge(1, 7, 11);
    g.addEdge(2, 3, 7);
    g.addEdge(2, 8, 2);
    g.addEdge(2, 5, 4);
    g.addEdge(3, 4, 9);
    g.addEdge(3, 5, 14);
    g.addEdge(4, 5, 10);
    g.addEdge(5, 6, 2);
    g.addEdge(6, 7, 1);
    g.addEdge(6, 8, 6);
    g.addEdge(7, 8, 7);

    g.shortestPath(0);
}

}

// This code is contributed by Susobhan Akhuli

JavaScript

class PriorityQueue { constructor() { this.queue = []; }

enqueue(element) {
    this.queue.push(element);
    this.queue.sort((a, b) => a[0] - b[0]);
}

dequeue() {
    if (this.isEmpty()) return "Queue is empty";
    return this.queue.shift();
}

isEmpty() {
    return this.queue.length === 0;
}

}

class Graph { constructor(V) { this.V = V; this.adj = new Array(V).fill().map(() => []); }

addEdge(u, v, w) {
    this.adj[u].push([v, w]);
    this.adj[v].push([u, w]);
}

shortestPath(src) {
    const pq = new PriorityQueue();
    const dist = new Array(this.V).fill(Infinity);

    pq.enqueue([0, src]);
    dist[src] = 0;

    while (!pq.isEmpty()) {
        const [uDist, u] = pq.dequeue();

        for (const [v, weight] of this.adj[u]) {
            if (dist[v] > dist[u] + weight) {
                dist[v] = dist[u] + weight;
                pq.enqueue([dist[v], v]);
            }
        }
    }

    console.log("Vertex Distance from Source");
    for (let i = 0; i < this.V; ++i) {
        console.log(i + "\t\t" + dist[i]);
    }
}

}

// Driver program to test methods of the graph class function main() { // create the graph given in the provided C++ code const V = 9; const g = new Graph(V);

g.addEdge(0, 1, 4);
g.addEdge(0, 7, 8);
g.addEdge(1, 2, 8);
g.addEdge(1, 7, 11);
g.addEdge(2, 3, 7);
g.addEdge(2, 8, 2);
g.addEdge(2, 5, 4);
g.addEdge(3, 4, 9);
g.addEdge(3, 5, 14);
g.addEdge(4, 5, 10);
g.addEdge(5, 6, 2);
g.addEdge(6, 7, 1);
g.addEdge(6, 8, 6);
g.addEdge(7, 8, 7);

g.shortestPath(0);

}

// Call the main function main();

`

Output

Vertex Distance from Source 0 0 1 4 2 12 3 19 4 21 5 11 6 9 7 8 8 14

**Time complexity : O(E log V)

**Space Complexity:O(V 2 ) , here V is number of Vertices.

A Quicker Implementation using **vector of pairs representation of weighted graph :

C++ `

// Program to find Dijkstra's shortest path using // priority_queue in STL #include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f

// iPair ==> Integer Pair typedef pair<int, int> iPair;

// To add an edge void addEdge(vector<pair<int, int> > adj[], int u, int v, int wt) { adj[u].push_back(make_pair(v, wt)); adj[v].push_back(make_pair(u, wt)); }

// Prints shortest paths from src to all other vertices void shortestPath(vector<pair<int, int> > adj[], int V, int src) { // Create a priority queue to store vertices that // are being preprocessed. This is weird syntax in C++. // Refer below link for details of this syntax // https://www.geeksforgeeks.org/implement-min-heap-using-stl/ priority_queue<iPair, vector, greater > pq;

// Create a vector for distances and initialize all
// distances as infinite (INF)
vector<int> dist(V, INF);

// Insert source itself in priority queue and initialize
// its distance as 0.
pq.push(make_pair(0, src));
dist[src] = 0;

/* Looping till priority queue becomes empty (or all
distances are not finalized) */
while (!pq.empty()) {
    // The first vertex in pair is the minimum distance
    // vertex, extract it from priority queue.
    // vertex label is stored in second of pair (it
    // has to be done this way to keep the vertices
    // sorted distance (distance must be first item
    // in pair)
    int u = pq.top().second;
    pq.pop();

    // Get all adjacent of u.
    for (auto x : adj[u]) {
        // Get vertex label and weight of current
        // adjacent of u.
        int v = x.first;
        int weight = x.second;

        // If there is shorted path to v through u.
        if (dist[v] > dist[u] + weight) {
            // Updating distance of v
            dist[v] = dist[u] + weight;
            pq.push(make_pair(dist[v], v));
        }
    }
}

// Print shortest distances stored in dist[]
printf("Vertex Distance from Source\n");
for (int i = 0; i < V; ++i)
    printf("%d \t\t %d\n", i, dist[i]);

}

// Driver program to test methods of graph class int main() { int V = 9; vector adj[V];

// making above shown graph
addEdge(adj, 0, 1, 4);
addEdge(adj, 0, 7, 8);
addEdge(adj, 1, 2, 8);
addEdge(adj, 1, 7, 11);
addEdge(adj, 2, 3, 7);
addEdge(adj, 2, 8, 2);
addEdge(adj, 2, 5, 4);
addEdge(adj, 3, 4, 9);
addEdge(adj, 3, 5, 14);
addEdge(adj, 4, 5, 10);
addEdge(adj, 5, 6, 2);
addEdge(adj, 6, 7, 1);
addEdge(adj, 6, 8, 6);
addEdge(adj, 7, 8, 7);

shortestPath(adj, V, 0);

return 0;

}

Java

// Java program for the above approach import java.util.*;

class GFG { private static final int INF = 0x3f3f3f3f;

// To add an edge
static void
addEdge(List<List<Pair<Integer, Integer> > > adj, int u,
        int v, int wt)
{
    adj.get(u).add(new Pair<>(v, wt));
    adj.get(v).add(new Pair<>(u, wt));
}

// Prints shortest paths from src to all other vertices
static void
shortestPath(List<List<Pair<Integer, Integer> > > adj,
             int V, int src)
{
    // Create a priority queue to store vertices that
    // are being preprocessed.
    PriorityQueue<Pair<Integer, Integer> > pq
        = new PriorityQueue<>(
            Comparator.comparingInt(Pair::getFirst));

    // Create a list for distances and initialize all
    // distances as infinite (INF)
    List<Integer> dist
        = new ArrayList<>(Collections.nCopies(V, INF));

    // Insert source itself in priority queue and
    // initialize its distance as 0.
    pq.add(new Pair<>(0, src));
    dist.set(src, 0);

    /* Looping till priority queue becomes empty (or all
    distances are not finalized) */
    while (!pq.isEmpty()) {
        // The first vertex in pair is the minimum
        // distance vertex, extract it from priority
        // queue. vertex label is stored in second of
        // pair (it has to be done this way to keep the
        // vertices sorted distance (distance must be
        // first item in pair)
        int u = pq.peek().getSecond();
        pq.poll();

        // Get all adjacent of u.
        for (Pair<Integer, Integer> x : adj.get(u)) {
            // Get vertex label and weight of current
            // adjacent of u.
            int v = x.getFirst();
            int weight = x.getSecond();

            // If there is a shorter path to v through
            // u.
            if (dist.get(v) > dist.get(u) + weight) {
                // Updating distance of v
                dist.set(v, dist.get(u) + weight);
                pq.add(new Pair<>(dist.get(v), v));
            }
        }
    }

    // Print shortest distances stored in dist[]
    System.out.println("Vertex Distance from Source");
    for (int i = 0; i < V; i++) {
        System.out.printf("%d \t\t %d\n", i,
                          dist.get(i));
    }
}

// Driver program to test methods of graph class
public static void main(String[] args)
{
    int V = 9;
    List<List<Pair<Integer, Integer> > > adj
        = new ArrayList<>(V);

    for (int i = 0; i < V; i++) {
        adj.add(new ArrayList<>());
    }

    // Making the above-shown graph
    addEdge(adj, 0, 1, 4);
    addEdge(adj, 0, 7, 8);
    addEdge(adj, 1, 2, 8);
    addEdge(adj, 1, 7, 11);
    addEdge(adj, 2, 3, 7);
    addEdge(adj, 2, 8, 2);
    addEdge(adj, 2, 5, 4);
    addEdge(adj, 3, 4, 9);
    addEdge(adj, 3, 5, 14);
    addEdge(adj, 4, 5, 10);
    addEdge(adj, 5, 6, 2);
    addEdge(adj, 6, 7, 1);
    addEdge(adj, 6, 8, 6);
    addEdge(adj, 7, 8, 7);

    shortestPath(adj, V, 0);
}

}

class Pair<T, U> { private T first; private U second;

public Pair(T first, U second)
{
    this.first = first;
    this.second = second;
}

public T getFirst() { return first; }

public U getSecond() { return second; }

}

// This code is contributed by Susobhan Akhuli

Python

import heapq

Function to add an edge to the adjacency list

def addEdge(adj, u, v, wt): adj[u].append((v, wt)) adj[v].append((u, wt))

Function to find the shortest paths from source to all other vertices

def shortestPath(adj, V, src): # Create a priority queue to store vertices that are being preprocessed pq = []

# Create an array for distances and initialize all distances as infinite (INF)
dist = [float('inf')] * V

# Insert source itself in the priority queue and initialize its distance as 0
heapq.heappush(pq, (0, src))
dist[src] = 0

# Loop until the priority queue becomes empty
while pq:
    # Extract the vertex with minimum distance from the priority queue
    distance, u = heapq.heappop(pq)

    # Get all adjacent vertices of u
    for v, weight in adj[u]:
        # If there is a shorter path to v through u
        if dist[v] > dist[u] + weight:
            # Update distance of v
            dist[v] = dist[u] + weight
            heapq.heappush(pq, (dist[v], v))

# Print shortest distances stored in dist[]
print("Vertex Distance from Source")
for i in range(V):
    print(i,"   ",dist[i])

Main function

def main(): V = 9 adj = [[] for _ in range(V)]

# Making the graph
addEdge(adj, 0, 1, 4)
addEdge(adj, 0, 7, 8)
addEdge(adj, 1, 2, 8)
addEdge(adj, 1, 7, 11)
addEdge(adj, 2, 3, 7)
addEdge(adj, 2, 8, 2)
addEdge(adj, 2, 5, 4)
addEdge(adj, 3, 4, 9)
addEdge(adj, 3, 5, 14)
addEdge(adj, 4, 5, 10)
addEdge(adj, 5, 6, 2)
addEdge(adj, 6, 7, 1)
addEdge(adj, 6, 8, 6)
addEdge(adj, 7, 8, 7)

# Finding shortest paths from source vertex 0
shortestPath(adj, V, 0)

Call the main function to execute the program

if name == "main": main()

C#

// C# program for the above approach using System; using System.Collections.Generic;

// Implement Priority Queue public class PriorityQueue where T : IComparable { private List heap;

public PriorityQueue() { heap = new List<T>(); }

public int Count => heap.Count;

public void Enqueue(T item)
{
    heap.Add(item);
    int i = heap.Count - 1;
    while (i > 0) {
        int parent = (i - 1) / 2;
        if (heap[parent].CompareTo(heap[i]) <= 0)
            break;
        Swap(parent, i);
        i = parent;
    }
}

public T Peek()
{
    if (heap.Count == 0)
        throw new InvalidOperationException(
            "Priority queue is empty");
    return heap[0];
}

public T Dequeue()
{
    if (heap.Count == 0)
        throw new InvalidOperationException(
            "Priority queue is empty");
    T result = heap[0];
    int lastIndex = heap.Count - 1;
    heap[0] = heap[lastIndex];
    heap.RemoveAt(lastIndex);
    lastIndex--;
    int current = 0;
    while (true) {
        int leftChild = current * 2 + 1;
        int rightChild = current * 2 + 2;
        if (leftChild > lastIndex)
            break;
        int minChild = leftChild;
        if (rightChild <= lastIndex
            && heap[rightChild].CompareTo(
                   heap[leftChild])
                   < 0)
            minChild = rightChild;
        if (heap[current].CompareTo(heap[minChild])
            <= 0)
            break;
        Swap(current, minChild);
        current = minChild;
    }
    return result;
}

private void Swap(int i, int j)
{
    T temp = heap[i];
    heap[i] = heap[j];
    heap[j] = temp;
}

}

// To store an integer pair public class Pair : IComparable { public int first, second;

public Pair(int first, int second)
{
    this.first = first;
    this.second = second;
}

public int CompareTo(Pair other)
{
    return this.second.CompareTo(other.second);
}

}

public class GFG { // Function to add an edge to the graph static void AddEdge(List[] adj, int u, int v, int wt) { adj[u].Add(new Pair(v, wt)); adj[v].Add(new Pair(u, wt)); }

// Function to print shortest paths from source to all
// other vertices
static void ShortestPath(List<Pair>[] adj, int V,
                         int src)
{
    // Create a priority queue to store vertices that
    // are being preprocessed
    PriorityQueue<Pair> pq = new PriorityQueue<Pair>();

    // Create an array for distances and initialize all
    // distances as infinite
    int[] dist = new int[V];
    Array.Fill(dist, int.MaxValue);

    // Insert source itself in priority queue and
    // initialize its distance as 0
    pq.Enqueue(new Pair(src, 0));
    dist[src] = 0;

    // Loop until priority queue becomes empty
    while (pq.Count > 0) {
        // Extract the minimum distance vertex from
        // priority queue
        int u = pq.Peek().first;
        pq.Dequeue();

        // Get all adjacent vertices of u
        foreach(var x in adj[u])
        {
            int v = x.first;
            int weight = x.second;

            // If there is a shorter path to v through u
            if (dist[v] > dist[u] + weight) {
                // Update distance of v
                dist[v] = dist[u] + weight;
                pq.Enqueue(new Pair(v, dist[v]));
            }
        }
    }

    // Print shortest distances stored in dist[]
    Console.WriteLine("Vertex Distance from Source");
    for (int i = 0; i < V; ++i) {
        Console.WriteLine($"{i}\t\t{dist[i]}");
    }
}

// Driver program to test methods of graph class
static void Main(string[] args)
{
    int V = 9;
    List<Pair>[] adj = new List<Pair>[ V ];

    // Initialize adjacency list
    for (int i = 0; i < V; i++) {
        adj[i] = new List<Pair>();
    }

    // Making above shown graph
    AddEdge(adj, 0, 1, 4);
    AddEdge(adj, 0, 7, 8);
    AddEdge(adj, 1, 2, 8);
    AddEdge(adj, 1, 7, 11);
    AddEdge(adj, 2, 3, 7);
    AddEdge(adj, 2, 8, 2);
    AddEdge(adj, 2, 5, 4);
    AddEdge(adj, 3, 4, 9);
    AddEdge(adj, 3, 5, 14);
    AddEdge(adj, 4, 5, 10);
    AddEdge(adj, 5, 6, 2);
    AddEdge(adj, 6, 7, 1);
    AddEdge(adj, 6, 8, 6);
    AddEdge(adj, 7, 8, 7);

    ShortestPath(adj, V, 0);
}

}

// This code is contributed by Susobhan Akhuli

JavaScript

// Function to add an edge to the adjacency list function addEdge(adj, u, v, wt) { adj[u].push([v, wt]); adj[v].push([u, wt]); }

// Function to find the shortest paths from source to all other vertices function shortestPath(adj, V, src) { // Create a priority queue to store vertices that are being preprocessed let pq = [];

// Create an array for distances and initialize all distances as infinite (INF)
let dist = new Array(V).fill(Number.POSITIVE_INFINITY);

// Insert source itself in the priority queue and initialize its distance as 0
pq.push([0, src]);
dist[src] = 0;

// Loop until the priority queue becomes empty
while (pq.length > 0) {
    // Extract the vertex with minimum distance from the priority queue
    let [distance, u] = pq.shift();

    // Get all adjacent vertices of u
    for (let i = 0; i < adj[u].length; i++) {
        let [v, weight] = adj[u][i];

        // If there is a shorter path to v through u
        if (dist[v] > dist[u] + weight) {
            // Update distance of v
            dist[v] = dist[u] + weight;
            pq.push([dist[v], v]);
        }
    }
    // Sort the priority queue based on distance
    pq.sort((a, b) => a[0] - b[0]);
}

// Print shortest distances stored in dist[]
console.log("Vertex Distance from Source");
for (let i = 0; i < V; i++) {
    console.log(i + "\t\t" + dist[i]);
}

}

// Main function function main() { const V = 9; const adj = Array.from({ length: V }, () => []);

// Making the graph
addEdge(adj, 0, 1, 4);
addEdge(adj, 0, 7, 8);
addEdge(adj, 1, 2, 8);
addEdge(adj, 1, 7, 11);
addEdge(adj, 2, 3, 7);
addEdge(adj, 2, 8, 2);
addEdge(adj, 2, 5, 4);
addEdge(adj, 3, 4, 9);
addEdge(adj, 3, 5, 14);
addEdge(adj, 4, 5, 10);
addEdge(adj, 5, 6, 2);
addEdge(adj, 6, 7, 1);
addEdge(adj, 6, 8, 6);
addEdge(adj, 7, 8, 7);

// Finding shortest paths from source vertex 0
shortestPath(adj, V, 0);

}

// Call the main function to execute the program main();

`

Output

Vertex Distance from Source 0 0 1 4 2 12 3 19 4 21 5 11 6 9 7 8 8 14

The **time complexity of Dijkstra's algorithm using a priority queue implemented with a binary heap is **O(Elog(V)), where E is the number of edges and V is the number of vertices in the graph.

The **space complexity of this implementation is **O(V+E), where V is the number of vertices and E is the number of edges.

C++ `

#include #include #include #include

using namespace std;

// Define a struct Node to store the values struct Node { int v; int distance;

// Define a comparator method to compare distance of two nodes
bool operator<(const Node& other) const {
    return distance > other.distance;
}

};

// Function to implement Dijkstra Algorithm to find shortest distance vector dijkstra(int V, vector<vector<pair<int, int>>>& adj, int S) { // Initialize a visited array and map vector visited(V, false); unordered_map<int, Node> m;

// Initialize a priority queue
priority_queue<Node> pq;

// Insert source node into map
m[S] = {S, 0};
// Add source node to priority queue
pq.push({S, 0});

// While the priority queue is not empty
while (!pq.empty()) {
    // Pop the node with the minimum distance from priority queue
    Node n = pq.top();
    pq.pop();

    // Get the vertex and distance
    int v = n.v;
    int distance = n.distance;

    // Mark the vertex as visited
    visited[v] = true;

    // Get the adjacency list of the vertex
    vector<pair<int, int>> adjList = adj[v];

    // For every adjacent node of the vertex
    for (const auto& edge : adjList) {
        // If the node is not yet visited
        if (!visited[edge.first]) {
            // If the node is not present in the map
            if (m.find(edge.first) == m.end()) {
                // Put the node in the map
                m[edge.first] = {v, distance + edge.second};
            } else {
                // Get the node from the map
                Node& sn = m[edge.first];

                // Check if the new distance is less than the current distance of the node
                if (distance + edge.second < sn.distance) {
                    // Update the node's distance
                    sn.v = v;
                    sn.distance = distance + edge.second;
                }
            }

            // Push the node to the priority queue
            pq.push({edge.first, distance + edge.second});
        }
    }
}

// Initialize a result vector
vector<int> result(V, 0);

// For every key in the map
for (const auto& entry : m) {
    // Add the distance of the node to the result
    result[entry.first] = entry.second.distance;
}

// Return the result vector
return result;

}

int main() { // Initialize adjacency list and map vector<vector<pair<int, int>>> adj; unordered_map<int, vector<pair<int, int>>> m;

// Initialize number of vertices and edges
int V = 6;
int E = 5;

// Define u, v, and w
vector<int> u = {0, 0, 1, 2, 4};
vector<int> v = {3, 5, 4, 5, 5};
vector<int> w = {9, 4, 4, 10, 3};

// For every edge
for (int i = 0; i < E; ++i) {
    // Create an edge pair
    pair<int, int> edge = {v[i], w[i]};

    // If u[i] is not present in map
    if (m.find(u[i]) == m.end()) {
        // Create a new adjacency list
        vector<pair<int, int>> adjList;
        m[u[i]] = adjList;
    }

    // Add the edge to the adjacency list
    m[u[i]].push_back(edge);

    // Create another edge pair
    pair<int, int> edge2 = {u[i], w[i]};

    // If v[i] is not present in map
    if (m.find(v[i]) == m.end()) {
        // Create a new adjacency list
        vector<pair<int, int>> adjList2;
        m[v[i]] = adjList2;
    }

    // Add the edge to the adjacency list
    m[v[i]].push_back(edge2);
}

// For every vertex
for (int i = 0; i < V; ++i) {
    // If the vertex is present in map
    if (m.find(i) != m.end()) {
        // Add the adjacency list to the main adjacency list
        adj.push_back(m[i]);
    } else {
        // Add null to the main adjacency list
        adj.push_back({});
    }
}

// Define source node
int S = 1;

// Call the dijkstra function
vector<int> result = dijkstra(V, adj, S);

// Print the result in the specified format
cout << "[";
for (int i = 0; i < V; ++i) {
    if (i > 0) {
        cout << ", ";
    }
    cout << result[i];
}
cout << "]";

return 0;

}

Java

import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.PriorityQueue;

public class DijkstraAlgoForShortestDistance {

static class Node implements Comparable<Node> {
    int v;
    int distance;

    public Node(int v, int distance)
    {
        this.v = v;
        this.distance = distance;
    }

    @Override public int compareTo(Node n)
    {
        if (this.distance <= n.distance) {
            return -1;
        }
        else {
            return 1;
        }
    }
}

static int[] dijkstra(
    int V,
    ArrayList<ArrayList<ArrayList<Integer> > > adj,
    int S)
{
    boolean[] visited = new boolean[V];
    HashMap<Integer, Node> map = new HashMap<>();
    PriorityQueue<Node> q = new PriorityQueue<>();

    map.put(S, new Node(S, 0));
    q.add(new Node(S, 0));

    while (!q.isEmpty()) {
        Node n = q.poll();
        int v = n.v;
        int distance = n.distance;
        visited[v] = true;

        ArrayList<ArrayList<Integer> > adjList
            = adj.get(v);
        for (ArrayList<Integer> adjLink : adjList) {

            if (visited[adjLink.get(0)] == false) {
                if (!map.containsKey(adjLink.get(0))) {
                    map.put(
                        adjLink.get(0),
                        new Node(v,
                                 distance
                                     + adjLink.get(1)));
                }
                else {
                    Node sn = map.get(adjLink.get(0));
                    if (distance + adjLink.get(1)
                        < sn.distance) {
                        sn.v = v;
                        sn.distance
                            = distance + adjLink.get(1);
                    }
                }
                q.add(new Node(adjLink.get(0),
                               distance
                                   + adjLink.get(1)));
            }
        }
    }

    int[] result = new int[V];
    for (int i = 0; i < V; i++) {
        result[i] = map.get(i).distance;
    }

    return result;
}

public static void main(String[] args)
{
    ArrayList<ArrayList<ArrayList<Integer> > > adj
        = new ArrayList<>();
    HashMap<Integer, ArrayList<ArrayList<Integer> > >
        map = new HashMap<>();

    int V = 6;
    int E = 5;
    int[] u = { 0, 0, 1, 2, 4 };
    int[] v = { 3, 5, 4, 5, 5 };
    int[] w = { 9, 4, 4, 10, 3 };

    for (int i = 0; i < E; i++) {
        ArrayList<Integer> edge = new ArrayList<>();
        edge.add(v[i]);
        edge.add(w[i]);

        ArrayList<ArrayList<Integer> > adjList;
        if (!map.containsKey(u[i])) {
            adjList = new ArrayList<>();
        }
        else {
            adjList = map.get(u[i]);
        }
        adjList.add(edge);
        map.put(u[i], adjList);

        ArrayList<Integer> edge2 = new ArrayList<>();
        edge2.add(u[i]);
        edge2.add(w[i]);

        ArrayList<ArrayList<Integer> > adjList2;
        if (!map.containsKey(v[i])) {
            adjList2 = new ArrayList<>();
        }
        else {
            adjList2 = map.get(v[i]);
        }
        adjList2.add(edge2);
        map.put(v[i], adjList2);
    }

    for (int i = 0; i < V; i++) {
        if (map.containsKey(i)) {
            adj.add(map.get(i));
        }
        else {
            adj.add(null);
        }
    }
    int S = 1;

    // Input sample
    //[0 [[3, 9], [5, 4]],
    // 1 [[4, 4]],
    // 2 [[5, 10]],
    // 3 [[0, 9]],
    // 4 [[1, 4], [5, 3]],
    // 5 [[0, 4], [2, 10], [4, 3]]
    //]
    int[] result
        = DijkstraAlgoForShortestDistance.dijkstra(
            V, adj, S);
    System.out.println(Arrays.toString(result));
}

}

Python

#Python #import modules import heapq

#Define a class Node to store the values class Node: def init(self, v, distance): self.v = v self.distance = distance #define a comparator method to compare distance of two nodes def lt(self, other): return self.distance < other.distance

#function to implement Dijkstra Algorithm to find shortest distance def dijkstra(V, adj, S): #initialize a visited list and map visited = [False] * V map = {} #initialize a priority queue q = [] #insert source node in map map[S] = Node(S, 0) #add source node to priority queue heapq.heappush(q, Node(S, 0)) #while the priority queue is not empty while q: #pop the node with minimum distance from priority queue n = heapq.heappop(q) #get the vertex and distance v = n.v distance = n.distance #mark the vertex as visited visited[v] = True #get the adjacent list of the vertex adjList = adj[v] #for every adjacent node of the vertex for edge in adjList: #if the node is not yet visited if visited[edge[0]] == False: #if the node is not present in map if edge[0] not in map: #put the node in map map[edge[0]] = Node(v, distance + edge[1]) else: #get the node from map sn = map[edge[0]] #check if the new distance is less than the current distance of the node if distance + edge[1] < sn.distance: #update the node's distance sn.v = v sn.distance = distance + edge[1] #push the node to priority queue heapq.heappush(q, Node(edge[0], distance + edge[1])) #initialize a result list result = [0] * V #for every key in map for key in map.keys(): #add the distance of the node to the result result[key] = map[key].distance #return the result list return result

#main function if name == 'main': #initialize adjacency list and map adj = [] map = {} #initialize number of vertices and edges V = 6 E = 5 #define u, v and w u = [0, 0, 1, 2, 4] v = [3, 5, 4, 5, 5] w = [9, 4, 4, 10, 3]

#for every edge
for i in range(E):
    #create an edge list
    edge = [v[i], w[i]]
    #if the u[i] is not present in map
    if u[i] not in map:
        #create a new adjacency list
        adjList = []
    else:
        #get the existing adjacency list
        adjList = map[u[i]]
    #add the edge to the adjacency list
    adjList.append(edge)
    #put the adjacency list in map
    map[u[i]] = adjList
    #create another edge list
    edge2 = [u[i], w[i]]
    #if the v[i] is not present in map
    if v[i] not in map:
        #create a new adjacency list
        adjList2 = []
    else:
        #get the existing adjacency list
        adjList2 = map[v[i]]
    #add the edge to the adjacency list
    adjList2.append(edge2)
    #put the adjacency list in map
    map[v[i]] = adjList2

#for every vertex
for i in range(V):
    #if the vertex is present in map
    if i in map:
        #add the adjacency list to the main adjacency list
        adj.append(map[i])
    else:
        #add null to the main adjacency list
        adj.append(None)
#define source node
S = 1
#call the dijkstra function
result = dijkstra(V, adj, S)
#print the result
print(result)

JavaScript

// Define a class Node to store the values class Node { constructor(v, distance) { this.v = v; this.distance = distance; } }

// Function to implement Dijkstra Algorithm to find the shortest distance function dijkstra(V, adj, S) { // Initialize a visited list and map let visited = new Array(V).fill(false); let map = {};

// Initialize a priority queue
let q = [];
// Insert source node in map
map[S] = new Node(S, 0);
// Add source node to priority queue
q.push(new Node(S, 0));

// While the priority queue is not empty
while (q.length > 0) {
    // Pop the node with minimum distance from priority queue
    let n = q.shift();
    // Get the vertex and distance
    let v = n.v;
    let distance = n.distance;
    // Mark the vertex as visited
    visited[v] = true;
    // Get the adjacent list of the vertex
    let adjList = adj[v];
    // For every adjacent node of the vertex
    for (let edge of adjList) {
        // If the node is not yet visited
        if (!visited[edge[0]]) {
            // If the node is not present in map
            if (!(edge[0] in map)) {
                // Create a new adjacency list
                let adjList = [];
                // Add the node to the adjacency list
                adjList.push(new Node(v, distance + edge[1]));
                // Put the adjacency list in map
                map[edge[0]] = adjList;
            } else {
                // Get the existing adjacency list
                let adjList = map[edge[0]];
                // Check if the new distance is less than the current distance of the node
                if (distance + edge[1] < adjList[0].distance) {
                    // Update the node's distance
                    adjList[0].v = v;
                    adjList[0].distance = distance + edge[1];
                }
            }
            // Push the node to priority queue
            q.push(new Node(edge[0], distance + edge[1]));
            // Sort the priority queue based on distance
            q.sort((a, b) => a.distance - b.distance);
        }
    }
}

// Initialize a result list
let result = new Array(V).fill(0);
// For every key in map
for (let key in map) {
    // Check if map[key] is not empty
    if (map[key].length > 0) {
        // Add the distance of the node to the result
        result[key] = map[key][0].distance;
    }
}
// Return the result list
return result;

}

// Main function function main() { // Initialize adjacency list and map let adj = []; let map = {}; // Initialize number of vertices and edges let V = 6; let E = 5; // Define u, v, and w let u = [0, 0, 1, 2, 4]; let v = [3, 5, 4, 5, 5]; let w = [9, 4, 4, 10, 3];

// For every edge
for (let i = 0; i < E; i++) {
    // If the u[i] is not present in map
    if (!(u[i] in map)) {
        // Create a new adjacency list
        map[u[i]] = [];
    }
    // Add the node to the adjacency list
    map[u[i]].push([v[i], w[i]]);

    // If the v[i] is not present in map
    if (!(v[i] in map)) {
        // Create a new adjacency list
        map[v[i]] = [];
    }
    // Add the node to the adjacency list
    map[v[i]].push([u[i], w[i]]);
}

// For every vertex
for (let i = 0; i < V; i++) {
    // If the vertex is present in map
    if (i in map) {
        // Add the adjacency list to the main adjacency list
        adj.push(map[i]);
    } else {
        // Add null to the main adjacency list
        adj.push(null);
    }
}

// Define source node
let S = 1;
// Call the dijkstra function
let result = dijkstra(V, adj, S);
// Print the result
console.log(result);

}

// Call the main function main();

// This code is contributed by shivamgupta0987654321

`

Output

[11, 0, 17, 20, 4, 7]

**Time Complexity: O(ElogV)
The time complexity is O(ElogV) where E is the number of edges and V is the number of vertices. This is because, for each vertex, we need to traverse all its adjacent vertices and update their distances, which takes O(E) time. Also, we use a Priority Queue which takes O(logV) time for each insertion and deletion.

**Space Complexity: O(V)
The space complexity is O(V) as we need to maintain a visited array of size V, a map of size V and a Priority Queue of size V.

**Further Optimization We can use a flag array to store what all vertices have been extracted from priority queue. This way we can avoid updating weights of items that have already been extracted.