Open In App

Dijkstra’s shortest path algorithm using set

Last Updated : 10 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a weighted undirected graph represented as an edge list and a source vertex src, find the shortest path distances from the source vertex to all other vertices in the graph. The graph contains V vertices, numbered from 0 to V - 1.

Example:

Input: src = 0, V = 5, edges[][] = [[0, 1, 4], [0, 2, 8], [1, 4, 6], [2, 3, 2], [3, 4, 10]]

1

Output: 0 4 8 10 10
Explanation: Shortest Paths:
0 to 1 = 4. 0 1
0 to 2 = 8. 0 2
0 to 3 = 10. 0 2 3
0 to 4 = 10. 0 1 4

Dijkstra’s Algorithm can be implemented using either a min-heap or a set. In this article, we’ll focus on the implementation using a set. For the min-heap version, you can refer to our article on Dijkstra’s Algorithm using a min-heap.

Dijkstra’s Algorithm using set

In Dijkstra’s Algorithm, the goal is to determine the shortest distance from a specified source node to every other node in the graph. As the source node is the starting point, its distance is initialized to zero. Then, we use an ordered set to keep track of unprocessed nodes, which allows us to efficiently extract the node with the smallest tentative distance. For each selected node u, we ‘relax’ its adjacent edges: for every neighbor v, we update its distance as dist[v] = dist[u] + weight[u][v] if this new path is shorter than the currently known distance. This process, using the set for efficient retrieval of the minimum element, repeats until all nodes have been processed.

For a deeper understanding of Dijkstra’s algorithm, refer to this resource.

Step-by-Step Implementation

  1. Set dist = 0 and all other distances as infinity.
  2. Insert the source node into the set as a pair <distance, node> → i.e., <0, source>.
  3. Extract the element with the smallest distance from the set.
  4. For each adjacent neighbor of the current node:
    • Calculate the tentative distance using the formula:
      dist[v] = dist[u] + weight[u][v]
    • If this new distance is shorter than the current dist[v]:
      • If v already exists in the set with its old distance, remove it.
      • Update dist[v] to the new shorter distance.
      • Insert the updated pair <dist[v], v> into the set.
  5. Repeat step 3 and 4 until the set becomes empty.
  6. Return the distance array dist[], which holds the shortest distance from the source to every other node.

In JavaScript and Python, the built-in Set data structure does not maintain elements in sorted order. This means if we use a Set, we would have to manually sort the elements each time we need the one with the smallest distance, which is inefficient.

Illustration:


C++
#include <iostream>
#include <vector>
#include <set>
#include <climits>
using namespace std;

// Function to construct adjacency list
vector<vector<vector<int>>> constructAdj(vector<vector<int>> &edges, int V){
    
    // adj[u] = list of {v, wt}
    vector<vector<vector<int>>> adj(V); 
    for (const auto &edge : edges) {
        int u = edge[0];
        int v = edge[1];
        int wt = edge[2];
        
        adj[u].push_back({v, wt});
        adj[v].push_back({u, wt}); 
    }
    return adj;
}

// Returns shortest distances from src to all other vertices
vector<int> shortestPath(int V, vector<vector<int>> &edges, int src) {
    vector<vector<vector<int>>> adj = constructAdj(edges, V);

    // Set to store {distance, node}
    set<pair<int, int>> st;

    // Distance vector initialized to INF
    vector<int> dist(V, INT_MAX);

    dist[src] = 0;
    st.insert({0, src});

    while (!st.empty()) {
        auto it = *(st.begin());
        int u = it.second;
        
        // Remove the node with the smallest distance
        st.erase(it); 

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

            // If shorter path found
            if (dist[v] > dist[u] + weight) {
                
                // If v already in set, erase the older (larger dist) entry
                if (dist[v] != INT_MAX) {
                    st.erase({dist[v], v});
                }
                dist[v] = dist[u] + weight;
                st.insert({dist[v], v});
            }
        }
    }

    return dist;
}

int main() {
    int V = 5;
    int src = 0;

    // edge list format: {u, v, weight}
    vector<vector<int>> edges = {{0, 1, 4}, {0, 2, 8}, {1, 4, 6},
                                 {2, 3, 2}, {3, 4, 10}};

    vector<int> result = shortestPath(V, edges, src);

    // Print shortest distances in one line
    for (int dist : result)
        cout << dist << " ";

    return 0;
}
Java
import java.util.*;

class GfG {

    // Function to construct adjacency 
    static List<int[]>[] constructAdj(int[][] edges, int V) {
        
        // Initialize the adjacency list
        List<int[]>[] adj = new ArrayList[V];
        for (int i = 0; i < V; i++)
            adj[i] = new ArrayList<>();

        // Fill the adjacency list from edges
        for (int[] edge : edges) {
            int u = edge[0];
            int v = edge[1];
            int wt = edge[2];
            adj[u].add(new int[]{v, wt});
            adj[v].add(new int[]{u, wt}); 
        }

        return adj;
    }

    // Returns shortest distances from src to all other vertices
    static int[] shortestPath(int V, int[][] edges, int src) {
        
        // Create adjacency list
        List<int[]>[] adj = constructAdj(edges, V);

        // TreeSet to store vertices that are being preprocessed.
        // It stores pairs as {distance, vertex} and automatically keeps them sorted.
        TreeSet<int[]> set = new TreeSet<>((a, b) -> {
            if (a[0] != b[0]) return Integer.compare(a[0], b[0]);
            return Integer.compare(a[1], b[1]);
        });

        // Create a vector for distances and initialize 
        // all distances as infinite
        int[] dist = new int[V];
        Arrays.fill(dist, Integer.MAX_VALUE);

        // Insert source itself in TreeSet and 
        // initialize its distance as 0.
        set.add(new int[]{0, src});
        dist[src] = 0;

        // Looping till TreeSet becomes empty 
        // (or all distances are not finalized)
        while (!set.isEmpty()) {
            // The first vertex in pair is the minimum distance
            // vertex, extract it from TreeSet.
            int[] top = set.pollFirst(); 
            int u = top[1];

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

                // If there is shorter path to v through u.
                if (dist[v] > dist[u] + weight) {
                    
                    if (dist[v] != Integer.MAX_VALUE) {
                        set.remove(new int[]{dist[v], v});
                    }
                    
                    // Updating distance of v
                    dist[v] = dist[u] + weight;
                    set.add(new int[]{dist[v], v});
                }
            }
        }

        // Return the shortest distance array
        return dist;
    }

    // Driver program to test methods of graph class
    public static void main(String[] args) {
        int V = 5;
        int src = 0;

        // edge list format: {u, v, weight}
        int[][] edges = {{0, 1, 4}, {0, 2, 8}, {1, 4, 6}, 
                           {2, 3, 2}, {3, 4, 10}}; 
                                 
        // Get shortest path distances
        int[] result = shortestPath(V, edges, src);

        // Print shortest distances in one line
        for (int d : result)
            System.out.print(d + " ");
    }
}
C#
using System;
using System.Collections.Generic;

class GfG{
    
    // Function to construct adjacency 
    static List<int[]>[] constructAdj(int[,] edges, int V){
        
        // adj[u] = list of {v, wt}
        List<int[]>[] adj = new List<int[]>[V];
        for (int i = 0; i < V; i++)
            adj[i] = new List<int[]>();
        // number of edges
        int E = edges.GetLength(0); 

        for (int i = 0; i < E; i++){
            int u = edges[i, 0];
            int v = edges[i, 1];
            int wt = edges[i, 2];
            adj[u].Add(new int[] { v, wt });
            adj[v].Add(new int[] { u, wt }); 
        }

        return adj;
    }

    // Custom comparer for SortedSet to act as a priority queue
    class PairComparer : IComparer<int[]>{
        
        public int Compare(int[] a, int[] b){
            
            // Compare by distance
            if (a[0] != b[0]) return a[0] - b[0];

            // Tie breaker by node id
            return a[1] - b[1];
        }
    }

    // Returns shortest distances from src to all other vertices
    static int[] shortestPath(int V, int[,] edges, int src){
        // Create adjacency list
        List<int[]>[] adj = constructAdj(edges, V);

        // Use SortedSet as a min-priority queue
        var pq = new SortedSet<int[]>(new PairComparer());

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

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

        // Looping till priority queue becomes empty
        while (pq.Count > 0){
            
            // The first vertex in pair is the minimum distance
            // vertex, extract it from priority queue.
            int[] top = GetAndRemoveFirst(pq);
            int u = top[1];

            // Get all adjacent of u.
            foreach (var x in adj[u]){
                
                // Get vertex label and weight of current
                // adjacent of u.
                int v = x[0];
                int weight = x[1];

                // If there is shorter path to v through u.
                if (dist[v] > dist[u] + weight){
                    
                    // Remove old pair if it exists
                    if (dist[v] != int.MaxValue)
                        pq.Remove(new int[] { dist[v], v }); 

                    // Updating distance of v
                    dist[v] = dist[u] + weight;
                    pq.Add(new int[] { dist[v], v });
                }
            }
        }

        // Return the shortest distance array
        return dist;
    }

    // Helper to remove and return the first element from SortedSet
    static int[] GetAndRemoveFirst(SortedSet<int[]> set){
        
        var first = set.Min;
        set.Remove(first);
        return first;
    }

    // Driver program to test methods of graph class
    static void Main(string[] args){
        
        int V = 5;
        int src = 0;

        // edge list format: {u, v, weight}
        int[,] edges = {{0, 1, 4}, {0, 2, 8}, {1, 4, 6}, 
                        {2, 3, 2}, {3, 4, 10}}; 

        int[] result = shortestPath(V, edges, src);

        // Print shortest distances in one line
        foreach (int dist in result)
            Console.Write(dist + " ");
    }
}

Output
0 4 8 10 10 

Time Complexity: O((V + E) × log V)
Space Complexity: O(V), Where V is the number of vertices, We do not count the adjacency list in auxiliary space as it is necessary for representing the input graph.



Next Article
Article Tags :
Practice Tags :

Similar Reads