Dijkstra’s shortest path algorithm using set (original) (raw)

Last Updated : 10 Apr, 2025

Try it on GfG Practice redirect icon

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[source] = 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 #include #include #include using namespace std;

// Function to construct adjacency list vector<vector<vector>> constructAdj(vector<vector> &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 shortestPath(int V, vector<vector> &edges, int src) { vector<vector<vector>> 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 + " ");
}

}

`

**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.