Dijkstra’s shortest path algorithm using set
Last Updated :
10 Apr, 2025
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]]
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
- Set
dist[source] = 0
and all other distances as infinity. - Insert the source node into the set as a pair
<distance, node>
→ i.e., <0, source>
. - Extract the element with the smallest distance from the set.
- 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.
- Repeat step 3 and 4 until the set becomes empty.
- 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 + " ");
}
}
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.