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 containsVvertices, numbered from 0 to V - 1.
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
Setdist[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.
Updatedist[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>usingnamespacestd;// Function to construct adjacency listvector<vector<vector<int>>>constructAdj(vector<vector<int>>&edges,intV){// adj[u] = list of {v, wt}vector<vector<vector<int>>>adj(V);for(constauto&edge:edges){intu=edge[0];intv=edge[1];intwt=edge[2];adj[u].push_back({v,wt});adj[v].push_back({u,wt});}returnadj;}// Returns shortest distances from src to all other verticesvector<int>shortestPath(intV,vector<vector<int>>&edges,intsrc){vector<vector<vector<int>>>adj=constructAdj(edges,V);// Set to store {distance, node}set<pair<int,int>>st;// Distance vector initialized to INFvector<int>dist(V,INT_MAX);dist[src]=0;st.insert({0,src});while(!st.empty()){autoit=*(st.begin());intu=it.second;// Remove the node with the smallest distancest.erase(it);for(autox:adj[u]){intv=x[0];intweight=x[1];// If shorter path foundif(dist[v]>dist[u]+weight){// If v already in set, erase the older (larger dist) entryif(dist[v]!=INT_MAX){st.erase({dist[v],v});}dist[v]=dist[u]+weight;st.insert({dist[v],v});}}}returndist;}intmain(){intV=5;intsrc=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 linefor(intdist:result)cout<<dist<<" ";return0;}
Java
importjava.util.*;classGfG{// Function to construct adjacency staticList<int[]>[]constructAdj(int[][]edges,intV){// Initialize the adjacency listList<int[]>[]adj=newArrayList[V];for(inti=0;i<V;i++)adj[i]=newArrayList<>();// Fill the adjacency list from edgesfor(int[]edge:edges){intu=edge[0];intv=edge[1];intwt=edge[2];adj[u].add(newint[]{v,wt});adj[v].add(newint[]{u,wt});}returnadj;}// Returns shortest distances from src to all other verticesstaticint[]shortestPath(intV,int[][]edges,intsrc){// Create adjacency listList<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=newTreeSet<>((a,b)->{if(a[0]!=b[0])returnInteger.compare(a[0],b[0]);returnInteger.compare(a[1],b[1]);});// Create a vector for distances and initialize // all distances as infiniteint[]dist=newint[V];Arrays.fill(dist,Integer.MAX_VALUE);// Insert source itself in TreeSet and // initialize its distance as 0.set.add(newint[]{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();intu=top[1];// Get all adjacent of u.for(int[]x:adj[u]){// Get vertex label and weight of current adjacent of u.intv=x[0];intweight=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(newint[]{dist[v],v});}// Updating distance of vdist[v]=dist[u]+weight;set.add(newint[]{dist[v],v});}}}// Return the shortest distance arrayreturndist;}// Driver program to test methods of graph classpublicstaticvoidmain(String[]args){intV=5;intsrc=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 distancesint[]result=shortestPath(V,edges,src);// Print shortest distances in one linefor(intd:result)System.out.print(d+" ");}}
C#
usingSystem;usingSystem.Collections.Generic;classGfG{// Function to construct adjacency staticList<int[]>[]constructAdj(int[,]edges,intV){// adj[u] = list of {v, wt}List<int[]>[]adj=newList<int[]>[V];for(inti=0;i<V;i++)adj[i]=newList<int[]>();// number of edgesintE=edges.GetLength(0);for(inti=0;i<E;i++){intu=edges[i,0];intv=edges[i,1];intwt=edges[i,2];adj[u].Add(newint[]{v,wt});adj[v].Add(newint[]{u,wt});}returnadj;}// Custom comparer for SortedSet to act as a priority queueclassPairComparer:IComparer<int[]>{publicintCompare(int[]a,int[]b){// Compare by distanceif(a[0]!=b[0])returna[0]-b[0];// Tie breaker by node idreturna[1]-b[1];}}// Returns shortest distances from src to all other verticesstaticint[]shortestPath(intV,int[,]edges,intsrc){// Create adjacency listList<int[]>[]adj=constructAdj(edges,V);// Use SortedSet as a min-priority queuevarpq=newSortedSet<int[]>(newPairComparer());// Create a vector for distances and initialize all// distances as infiniteint[]dist=newint[V];for(inti=0;i<V;i++)dist[i]=int.MaxValue;// Insert source itself in priority queue and initialize// its distance as 0.pq.Add(newint[]{0,src});dist[src]=0;// Looping till priority queue becomes emptywhile(pq.Count>0){// The first vertex in pair is the minimum distance// vertex, extract it from priority queue.int[]top=GetAndRemoveFirst(pq);intu=top[1];// Get all adjacent of u.foreach(varxinadj[u]){// Get vertex label and weight of current// adjacent of u.intv=x[0];intweight=x[1];// If there is shorter path to v through u.if(dist[v]>dist[u]+weight){// Remove old pair if it existsif(dist[v]!=int.MaxValue)pq.Remove(newint[]{dist[v],v});// Updating distance of vdist[v]=dist[u]+weight;pq.Add(newint[]{dist[v],v});}}}// Return the shortest distance arrayreturndist;}// Helper to remove and return the first element from SortedSetstaticint[]GetAndRemoveFirst(SortedSet<int[]>set){varfirst=set.Min;set.Remove(first);returnfirst;}// Driver program to test methods of graph classstaticvoidMain(string[]args){intV=5;intsrc=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 lineforeach(intdistinresult)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.