Shortest Path यानि Dijkstra Algorithm
In this page:
import heapq
dist = {v: float('inf') for v in graph}
dist[source] = 0
heap = [(0, source)]
while heap:
d, u = heapq.heappop(heap)
for v, w in graph[u]:
if d + w < dist[v]:
dist[v] = d + w
heapq.heappush(heap, (dist[v], v))
What is Dijkstra
Dijkstra का algorithm एक starting vertex से हर दूसरे vertex तक shortest distance ढूंढता है, लेकिन सिर्फ तब सही काम करता है जब सभी edge weights zero या positive हों — एक negative edge इसे permanently गलत answer पर settle करा सकता है।
उदाहरण: What is Dijkstra
#include <iostream>
using namespace std;
int main() {
int weights[] = {4, 2, -1};
cout << "Weight -1 present: Dijkstra would settle on a wrong shortest distance here";
return 0;
}
public class Main {
public static void main(String[] args) {
int[] weights = {4, 2, -1};
System.out.println("Weight -1 present: Dijkstra would settle on a wrong shortest distance here");
}
}
weights = [4, 2, -1]
print("Weight -1 present: Dijkstra would settle on a wrong shortest distance here")
#include <stdio.h>
int main() {
int weights[] = {4, 2, -1};
printf("Weight -1 present: Dijkstra would settle on a wrong shortest distance here");
return 0;
}
Login to try C/C++/Java code in the editor
Relaxation
किसी edge को relax करने का मतलब है यह जांचना कि इससे होकर जाना किसी vertex तक currently recorded से एक छोटी known distance देता है या नहीं, और अगर हां तो वह distance update करना — पूरे algorithm में repeated होने वाला core operation।
उदाहरण: Relaxation
#include <iostream>
using namespace std;
int main() {
int dist[] = {0, 10, 1000000};
int u = 1, v = 2, weight = 3;
if (dist[u] + weight < dist[v]) {
cout << "Relax: dist[" << v << "] updated from " << dist[v] << " to " << dist[u]+weight;
dist[v] = dist[u] + weight;
}
return 0;
}
public class Main {
public static void main(String[] args) {
int[] dist = {0, 10, 1000000};
int u = 1, v = 2, weight = 3;
if (dist[u] + weight < dist[v]) {
System.out.println("Relax: dist[" + v + "] updated from " + dist[v] + " to " + (dist[u]+weight));
}
}
}
dist = [0, 10, 1000000]
u, v, weight = 1, 2, 3
if dist[u] + weight < dist[v]:
print(f"Relax: dist[{v}] updated from {dist[v]} to {dist[u]+weight}")
#include <stdio.h>
int main() {
int dist[] = {0, 10, 1000000};
int u = 1, v = 2, weight = 3;
if (dist[u] + weight < dist[v]) printf("Relax: dist[%d] updated from %d to %d", v, dist[v], dist[u]+weight);
return 0;
}
Login to try C/C++/Java code in the editor
Non-Negative Weights
Non-negative-weight requirement इसलिए मौजूद है क्योंकि Dijkstra एक बार process होने के बाद किसी vertex की distance permanently finalize करता है, यह मानते हुए कि कोई भविष्य की discovery कभी एक shorter path produce नहीं कर सकती — यह guarantee तुरंत टूट जाती है जैसे ही एक negative edge allowed हो।
उदाहरण: Non-Negative Weights
#include <iostream>
using namespace std;
int main() {
int finalized = 5;
cout << "Vertex " << finalized << " finalized: no future edge can ever shorten it since all weights are >= 0";
return 0;
}
public class Main {
public static void main(String[] args) {
int finalized = 5;
System.out.println("Vertex " + finalized + " finalized: no future edge can ever shorten it since all weights are >= 0");
}
}
finalized = 5
print(f"Vertex {finalized} finalized: no future edge can ever shorten it since all weights are >= 0")
#include <stdio.h>
int main() {
int finalized = 5;
printf("Vertex %d finalized: no future edge can ever shorten it since all weights are >= 0", finalized);
return 0;
}
Login to try C/C++/Java code in the editor
Example
एक road network की कल्पना करें जहां हर road का एक positive travel time हो: एक city से शुरू करते हुए, Dijkstra हर दूसरी city तक shortest travel time discover करता है हमेशा currently-closest unvisited city से बाहर की ओर expand करके।
उदाहरण: Example
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int main() {
vector<vector<pair<int,int>>> adj = {{{1,4},{2,1}},{{3,1}},{{1,1},{3,5}},{}};
vector<int> dist(4, 1000000); dist[0] = 0;
priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;
pq.push({0,0});
while (!pq.empty()) {
auto [d,u] = pq.top(); pq.pop();
if (d > dist[u]) continue;
for (auto [v,w] : adj[u]) if (dist[u]+w < dist[v]) { dist[v]=dist[u]+w; pq.push({dist[v],v}); }
}
cout << "Shortest travel time to city 3: " << dist[3];
return 0;
}
import java.util.*;
public class Main {
public static void main(String[] args) {
int[][][] adj = {{{1,4},{2,1}},{{3,1}},{{1,1},{3,5}},{}};
int[] dist = {0,1000000,1000000,1000000};
PriorityQueue<int[]> pq = new PriorityQueue<>((a,b)->a[0]-b[0]);
pq.add(new int[]{0,0});
while (!pq.isEmpty()) {
int[] cur = pq.poll();
int d = cur[0], u = cur[1];
if (d > dist[u]) continue;
for (int[] edge : adj[u]) {
int v = edge[0], w = edge[1];
if (dist[u]+w < dist[v]) { dist[v] = dist[u]+w; pq.add(new int[]{dist[v],v}); }
}
}
System.out.println("Shortest travel time to city 3: " + dist[3]);
}
}
import heapq
adj = [[(1,4),(2,1)],[(3,1)],[(1,1),(3,5)],[]]
dist = [1000000]*4
dist[0] = 0
pq = [(0,0)]
while pq:
d, u = heapq.heappop(pq)
if d > dist[u]:
continue
for v, w in adj[u]:
if dist[u] + w < dist[v]:
dist[v] = dist[u] + w
heapq.heappush(pq, (dist[v], v))
print("Shortest travel time to city 3:", dist[3])
#include <stdio.h>
int main() {
int dist[4] = {0, 1000000, 1000000, 1000000};
int edges[4][3] = {{0,1,4},{0,2,1},{2,1,1},{2,3,5}};
for (int pass = 0; pass < 3; pass++)
for (int i = 0; i < 4; i++)
if (dist[edges[i][0]] + edges[i][2] < dist[edges[i][1]])
dist[edges[i][1]] = dist[edges[i][0]] + edges[i][2];
printf("Shortest travel time to city 3: %d", dist[3]);
return 0;
}
Login to try C/C++/Java code in the editor
Complexity
अगला-closest vertex हमेशा चुनने के लिए एक min-priority queue उपयोग करना running time को roughly O((V+E) log V) तक लाता है; एक heap के बिना naive array scan O(V²) लेता है, जो छोटे या dense graphs के लिए ठीक है लेकिन बड़े sparse वालों के लिए धीमा है।
उदाहरण: Complexity
#include <iostream>
using namespace std;
int main() {
cout << "Dijkstra with min-heap: O((V+E) log V); naive array scan: O(V^2)";
return 0;
}
public class Main {
public static void main(String[] args) {
System.out.println("Dijkstra with min-heap: O((V+E) log V); naive array scan: O(V^2)");
}
}
print("Dijkstra with min-heap: O((V+E) log V); naive array scan: O(V^2)")
#include <stdio.h>
int main() {
printf("Dijkstra with min-heap: O((V+E) log V); naive array scan: O(V^2)");
return 0;
}
Login to try C/C++/Java code in the editor
- Negative weights वाले graph पर Dijkstra चलाना, जो गलत distances दे सकता है।
- Distances को
INT_MAXinitialize करना और फिर इसमें एक weight जोड़ना, जो overflow करता है। - Distance finalize होने के बाद किसी vertex को फिर process करना, या stale queue entries skip करना भूल जाना।
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: