Dijkstra’s Algorithm Using Priority Queue - Visualization

Problem Statement

You are given a weighted, undirected, and connected graph with V vertices represented using an adjacency list. Each entry adj[i] contains a list of lists, where each sublist contains two integers j and weight, representing an edge from vertex i to vertex j with a given weight.

Given a source vertex S, your task is to find the shortest distances from S to all other vertices using Dijkstra’s Algorithm and return them as a list.

Examples

Vertices Adjacency List Source Shortest Distances
3 [ [ [1, 1], [2, 4] ], [ [0, 1], [2, 2] ], [ [0, 4], [1, 2] ] ] 0 [0, 1, 3]
2 [ [ [1, 5] ], [ [0, 5] ] ] 1 [5, 0]
1 [ [] ] 0 [0]
4 [ [ [1, 2] ], [ [0, 2], [2, 1] ], [ [1, 1], [3, 5] ], [ [2, 5] ] ] 0 [0, 2, 3, 8]

Solution

Understanding the Problem

We are given a weighted graph and a starting node (source). Our goal is to find the shortest distance from this source to all other nodes in the graph.

In other words, for every node in the graph, we want to calculate the minimum possible sum of edge weights required to reach that node from the source.

This problem is a classic case of finding single-source shortest paths in graphs with non-negative weights, and Dijkstra’s Algorithm is an efficient way to solve it using a priority queue.

Step-by-Step Solution with Example

Step 1: Choose an Example

Let's consider the following weighted graph with 5 nodes (0 to 4), and the edges:


0 --(2)--> 1
0 --(4)--> 2
1 --(1)--> 2
1 --(7)--> 3
2 --(3)--> 4
3 --(1)--> 4

We want to find the shortest distance from node 0 to all other nodes.

Step 2: Initialize the Distance Array

Create a distance[] array and fill it with Infinity to represent that we don’t yet know the shortest path. Set the distance of the source node to 0.


distance = [0, ∞, ∞, ∞, ∞]

Step 3: Use a Min-Heap (Priority Queue)

Use a priority queue (min-heap) to always pick the next node with the smallest known distance. Initially, insert the source node with distance 0:


priorityQueue = [(0, 0)]  // (distance, node)

Step 4: Start the Main Loop

While the priority queue is not empty:

  1. Extract the node with the smallest distance.
  2. Explore all its neighbors.
  3. If a shorter path to a neighbor is found, update the distance and insert it into the queue.

Step 5: Trace the Execution for Our Example

  • Start with node 0, distance 0.
  • Check edges: (0 → 1, weight 2), (0 → 2, weight 4)
  • Update: distance[1] = 2, distance[2] = 4
  • Queue: [(2,1), (4,2)]
  • Next node: 1, distance 2
  • Check edges: (1 → 2, weight 1) → 2 + 1 = 3 is better than current 4, update distance[2] = 3
  • Also (1 → 3, weight 7) → distance[3] = 9
  • Queue: [(3,2), (4,2), (9,3)]
  • Next node: 2, distance 3
  • Check edge (2 → 4, weight 3) → distance[4] = 6
  • Queue: [(4,2), (9,3), (6,4)]
  • Next node: 4, distance 6 → Already the best.
  • Check edge (4 → 3, weight 1) → 6 + 1 = 7 is better than 9 → update distance[3] = 7

Step 6: Final Distance Array


distance = [0, 2, 3, 7, 6]

This gives the shortest path from node 0 to every other node in the graph.

Edge Cases

  • Disconnected Graph: If a node is not reachable from the source, its distance will remain Infinity.
  • Zero Weight Edges: Dijkstra’s algorithm handles them correctly as long as weights are non-negative.
  • Multiple Edges Between Nodes: Always consider the one with the minimum weight during edge relaxation.
  • Self-loops: They can be ignored unless required for the specific application.

Finally

Dijkstra’s Algorithm is a powerful tool for finding the shortest paths in a graph with non-negative weights. Using a priority queue helps efficiently expand the closest node at every step. Always remember to initialize distances properly and carefully update them when a shorter path is found. This algorithm is widely used in routing, pathfinding, and network optimization problems.

Algorithm Steps

  1. Initialize dist[] with Infinity, set dist[S] = 0.
  2. Create a priority queue (min-heap) and insert {0, S}.
  3. While the queue is not empty:
    1. Pop the vertex with the minimum distance from the queue.
    2. For each adjacent vertex v of the current node:
      1. If dist[u] + weight < dist[v], update dist[v] and add {dist[v], v} to the queue.
  4. Return dist[] as the shortest distances from source S.

Code

C
C++
Python
Java
JS
Go
Rust
Kotlin
Swift
TS
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>

#define V 3

int minDistance(int dist[], bool sptSet[]) {
    int min = INT_MAX, min_index;
    for (int v = 0; v < V; v++) {
        if (!sptSet[v] && dist[v] <= min) {
            min = dist[v], min_index = v;
        }
    }
    return min_index;
}

void dijkstra(int graph[V][V], int src) {
    int dist[V];
    bool sptSet[V];

    for (int i = 0; i < V; i++) {
        dist[i] = INT_MAX, sptSet[i] = false;
    }

    dist[src] = 0;

    for (int count = 0; count < V - 1; count++) {
        int u = minDistance(dist, sptSet);
        sptSet[u] = true;

        for (int v = 0; v < V; v++) {
            if (!sptSet[v] && graph[u][v] &&
                dist[u] != INT_MAX &&
                dist[u] + graph[u][v] < dist[v]) {
                dist[v] = dist[u] + graph[u][v];
            }
        }
    }

    printf("Shortest distances:\n");
    for (int i = 0; i < V; i++) {
        printf("%d ", dist[i]);
    }
}

int main() {
    int graph[V][V] = {
        {0, 1, 4},
        {1, 0, 2},
        {4, 2, 0}
    };
    dijkstra(graph, 0);
    return 0;
}

Comments

💬 Please keep your comment relevant and respectful. Avoid spamming, offensive language, or posting promotional/backlink content.
All comments are subject to moderation before being published.


Loading comments...