Given a weighted undirected graph and a source vertex src. We need to find the shortest path distances from the source vertex to all other vertices in the graph. Note: The given graph does not contain any negative edge.
The idea is to maintain distance using an array dist[] from the given source to all vertices. The distance array is initialized as infinite for all vertexes and 0 for the given source We also maintain two sets,
One set contains vertices included in the shortest-path tree,
The other set includes vertices not yet included in the shortest-path tree.
At every step of the algorithm, find a vertex that is in the other set (set not yet included) and has a minimum distance from the source. Once we pick a vertex, we update the distance of its adjacent if we get a shorter path through it.
Use of priority Queue
The priority queue always selects the node with the smallest current distance, ensuring that we explore the shortest paths first and avoid unnecessary processing of longer paths. Dijkstra’s algorithm always picks the node with the minimum distance first. By doing so, it ensures that the node has already checked the shortest distance to all its neighbors. If this node appears again in the priority queue later, we don’t need to process it again, because its neighbors have already checked the minimum possible distances
Detailed Steps:
Create a distance array dist[] of size V and initialize all values to infinity (∞) since no paths are known yet.
Set the distance of the source vertex to 0 and insert it into the priority queue.
While the priority queue is not empty, remove the vertex with the smallest distance value.
Check: if the popped distance is greater than the recorded distance for this vertex(dist[u]), it means this vertex has already been processed with a smaller distance, so skip it and continue to the next iteration.
For each neighbor v of u, check if the path through u gives a smaller distance than the current dist[v]. If it does, update dist[v] = dist[u] + edge weight(d) and push (dist[v], v) into the priority queue.
Continue this process until the priority queue becomes empty.
Once done, the dist[] array will contain the shortest distance from the source to every vertex in the graph.\
C++
//Driver Code Starts#include<iostream>#include<vector>#include<queue>#include<climits>usingnamespacestd;//Driver Code Endsvector<int>dijkstra(vector<vector<pair<int,int>>>&adj,intsrc){intV=adj.size();// Min-heap (priority queue) storing pairs of (distance, node)priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>pq;vector<int>dist(V,INT_MAX);// Distance from source to itself is 0dist[src]=0;pq.emplace(0,src);// Process the queue until all reachable vertices are finalizedwhile(!pq.empty()){autotop=pq.top();pq.pop();intd=top.first;intu=top.second;// If this distance not the latest shortest one, skip itif(d>dist[u])continue;// Explore all neighbors of the current vertexfor(auto&p:adj[u]){intv=p.first;intw=p.second;// If we found a shorter path to v through u, update itif(dist[u]+w<dist[v]){dist[v]=dist[u]+w;pq.emplace(dist[v],v);}}}// Return the final shortest distances from the sourcereturndist;}//Driver Code Startsintmain(){intsrc=0;vector<vector<pair<int,int>>>adj(5);adj[0]={{1,4},{2,8}};adj[1]={{0,4},{4,6},{2,3}};adj[2]={{0,8},{3,2},{1,3}};adj[3]={{2,2},{4,10}};adj[4]={{1,6},{3,10}};vector<int>result=dijkstra(adj,src);for(intd:result)cout<<d<<" ";cout<<"";return0;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.ArrayList;importjava.util.Arrays;importjava.util.PriorityQueue;classGFG{//Driver Code EndsstaticArrayList<Integer>dijkstra(ArrayList<ArrayList<int[]>>adj,intsrc){intV=adj.size();// Min-heap (priority queue) storing pairs of (distance, node)PriorityQueue<int[]>pq=newPriorityQueue<>((a,b)->a[0]-b[0]);// Distance array: stores shortest distance from sourceint[]dist=newint[V];Arrays.fill(dist,Integer.MAX_VALUE);// Distance from source to itself is 0dist[src]=0;pq.offer(newint[]{0,src});// Process the queue until all reachable vertices are finalizedwhile(!pq.isEmpty()){int[]top=pq.poll();intd=top[0];intu=top[1];// If this distance is not the latest shortest one, skip itif(d>dist[u])continue;// Explore all adjacent verticesfor(int[]p:adj.get(u)){intv=p[0];intw=p[1];// If we found a shorter path to v through u, update itif(dist[u]+w<dist[v]){dist[v]=dist[u]+w;pq.offer(newint[]{dist[v],v});}}}ArrayList<Integer>result=newArrayList<>();for(intd:dist)result.add(d);// Return the final shortest distances from the sourcereturnresult;}//Driver Code StartsstaticvoidaddEdge(ArrayList<ArrayList<int[]>>adj,intu,intv,intw){adj.get(u).add(newint[]{v,w});adj.get(v).add(newint[]{u,w});}publicstaticvoidmain(String[]args){intV=5;intsrc=0;ArrayList<ArrayList<int[]>>adj=newArrayList<>();for(inti=0;i<V;i++){adj.add(newArrayList<>());}addEdge(adj,0,1,4);addEdge(adj,0,2,8);addEdge(adj,1,4,6);addEdge(adj,1,2,3);addEdge(adj,2,3,2);addEdge(adj,3,4,10);ArrayList<Integer>result=dijkstra(adj,src);for(intd:result)System.out.print(d+" ");System.out.println();}}//Driver Code Ends
Python
#Driver Code Startsimportheapqimportsys#Driver Code Endsdefdijkstra(adj,src):V=len(adj)# Min-heap (priority queue) storing pairs of (distance, node)pq=[]dist=[sys.maxsize]*V# Distance from source to itself is 0dist[src]=0heapq.heappush(pq,(0,src))# Process the queue until all reachable vertices are finalizedwhilepq:d,u=heapq.heappop(pq)# If this distance not the latest shortest one, skip itifd>dist[u]:continue# Explore all neighbors of the current vertexforv,winadj[u]:# If we found a shorter path to v through u, update itifdist[u]+w<dist[v]:dist[v]=dist[u]+wheapq.heappush(pq,(dist[v],v))# Return the final shortest distances from the sourcereturndist#Driver Code Startsif__name__=="__main__":src=0adj=[[(1,4),(2,8)],[(0,4),(4,6),(2,3)],[(0,8),(3,2),(1,3)],[(2,2),(4,10)],[(1,6),(3,10)]]result=dijkstra(adj,src)print(*result)#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;classMinHeap{privateList<int[]>heap;publicMinHeap(){heap=newList<int[]>();}publicintCount=>heap.Count;// Enqueue (node, distance)publicvoidEnqueue(intnode,intdistance){heap.Add(newint[]{distance,node});SiftUp(heap.Count-1);}// Dequeue the smallest distance pairpublicboolTryDequeue(outintnode,outintdistance){if(heap.Count==0){node=-1;distance=int.MaxValue;returnfalse;}int[]top=heap[0];distance=top[0];node=top[1];intlast=heap.Count-1;heap[0]=heap[last];heap.RemoveAt(last);if(heap.Count>0)SiftDown(0);returntrue;}privatevoidSiftUp(inti){while(i>0){intparent=(i-1)/2;if(heap[parent][0]<=heap[i][0])break;Swap(i,parent);i=parent;}}privatevoidSiftDown(inti){intn=heap.Count;while(true){intleft=2*i+1;intright=2*i+2;intsmallest=i;if(left<n&&heap[left][0]<heap[smallest][0])smallest=left;if(right<n&&heap[right][0]<heap[smallest][0])smallest=right;if(smallest==i)break;Swap(i,smallest);i=smallest;}}privatevoidSwap(inti,intj){int[]temp=heap[i];heap[i]=heap[j];heap[j]=temp;}}classGFG{//Driver Code EndsstaticList<int>dijkstra(List<List<int[]>>adj,intsrc){intV=adj.Count;// Min-heap (priority queue) storing pairs of (distance, node)MinHeappq=newMinHeap();// Distance array: stores shortest distance from sourceint[]dist=newint[V];for(inti=0;i<V;i++)dist[i]=int.MaxValue;// Distance from source to itself is 0dist[src]=0;pq.Enqueue(src,0);// Process the queue until all reachable vertices are finalizedwhile(pq.Count>0){pq.TryDequeue(outintu,outintd);// If this distance is not the latest shortest one, skip itif(d>dist[u])continue;// Explore all adjacent verticesforeach(varpinadj[u]){intv=p[0];intw=p[1];// If we found a shorter path to v through u, update itif(dist[u]+w<dist[v]){dist[v]=dist[u]+w;pq.Enqueue(v,dist[v]);}}}// Convert result to List for outputList<int>result=newList<int>();foreach(intdindist)result.Add(d);// Return the final shortest distances from the sourcereturnresult;}//Driver Code StartsstaticvoidaddEdge(List<List<int[]>>adj,intu,intv,intw){adj[u].Add(newint[]{v,w});adj[v].Add(newint[]{u,w});}staticvoidMain(){intV=5;intsrc=0;List<List<int[]>>adj=newList<List<int[]>>();for(inti=0;i<V;i++)adj.Add(newList<int[]>());addEdge(adj,0,1,4);addEdge(adj,0,2,8);addEdge(adj,1,2,3);addEdge(adj,1,4,6);addEdge(adj,2,3,2);addEdge(adj,3,4,10);List<int>result=dijkstra(adj,src);foreach(intdinresult)Console.Write(d+" ");Console.WriteLine();}}//Driver Code Ends
JavaScript
//Driver Code StartsclassMinHeap{constructor(){this.heap=[];}push(item){this.heap.push(item);this._bubbleUp();}pop(){if(this.heap.length===1)returnthis.heap.pop();consttop=this.heap[0];this.heap[0]=this.heap.pop();this._bubbleDown();returntop;}_bubbleUp(){leti=this.heap.length-1;while(i>0){letp=Math.floor((i-1)/2);if(this.heap[p][0]<=this.heap[i][0])break;[this.heap[p],this.heap[i]]=[this.heap[i],this.heap[p]];i=p;}}_bubbleDown(){leti=0;constn=this.heap.length;while(true){letl=2*i+1,r=2*i+2,smallest=i;if(l<n&&this.heap[l][0]<this.heap[smallest][0])smallest=l;if(r<n&&this.heap[r][0]<this.heap[smallest][0])smallest=r;if(smallest===i)break;[this.heap[i],this.heap[smallest]]=[this.heap[smallest],this.heap[i]];i=smallest;}}isEmpty(){returnthis.heap.length===0;}}//Driver Code Endsfunctiondijkstra(adj,src){letV=adj.length;// Min-heap (priority queue) storing pairs of (distance, node)letpq=newMinHeap();letdist=Array(V).fill(Number.MAX_SAFE_INTEGER);// Distance from source to itself is 0dist[src]=0;pq.push([0,src]);// Process the queue until all reachable vertices are finalizedwhile(!pq.isEmpty()){let[d,u]=pq.pop();// If this distance not the latest shortest one, skip itif(d>dist[u])continue;// Explore all neighbors of the current vertexfor(let[v,w]ofadj[u]){// If we found a shorter path to v through u, update itif(dist[u]+w<dist[v]){dist[v]=dist[u]+w;pq.push([dist[v],v]);}}}// Return the final shortest distances from the sourcereturndist;}//Driver Code Starts// Driver Codeletsrc=0;letadj=[[[1,4],[2,8]],[[0,4],[4,6],[2,3]],[[0,8],[3,2],[1,3]],[[2,2],[4,10]],[[1,6],[3,10]]];letresult=dijkstra(adj,src);console.log(result.join(" "));//Driver Code Ends
Output
0 4 7 9 10
Time Complexity: O((V+E)*logV), Where E is the number of edges and V is the number of vertices. Auxiliary Space: O(V+E)
How Does it Work?
Once we pop the minimum distance item from the priority queue, we finalize its shortest distance and never consider it again. Assuming that there are no negative weight edges, if there were a shorter path to this node through any other route, that path would have to go through nodes with equal or greater than current distance, and so wouldn’t be shorter
Why Does Not Work with Negative Weights:
Dijkstra’s algorithm assumes that once a vertex u is picked from the priority queue (meaning it currently has the smallest distance), its shortest distance is finalized - it will never change in the future. This assumption is true only if all edge weights are non-negative. Suppose there exists an edge with a negative weight. After Dijkstra finalizes a vertex u, there might exist another path through some vertex v (processed later) that leads back to u with a smaller total distance because of the negative edge. So, the algorithm’s earlier assumption that dist[u] was final is no longer valid.