Dijkstra's Shortest path Algorithm
Introduction:
This is a single source shortest path Algorithm where there is a single source from which we want to find shortest path to a node or to all other nodes.
Problem Statement:
find the shortest paths to all nodes from a start node.
Algorithm
1. A graph \(G(V, E)\) and start vertex \(s\) are given.
2. We create vertex set containing all vertices.
3. we have two arrays \(dist[\ ]\) initialized to \(\infty\) and \(prev[\ ]\) initilaized to -1 for all vertices
4. we make \(dist[s] = 0\).
5. while queue is not empty we pop vertex \(u\) from queue which has shortest value for \(dist[u]\).
6. for each vertex v in adjacency_list of u and in queue check if dist[v] can be relaxed i.e., check if \(dist[u]+ weightofedge(u, v) < dist[v]\) and accordingly update dist[v]
Pseudo code :
(source wikipedia)
function Dijkstra(Graph, source): dist[source] ← 0 // Initialization create vertex priority queue Q for each vertex v in Graph: if v ≠ source dist[v] ← INFINITY // Unknown distance from source to v prev[v] ← UNDEFINED // Predecessor of v Q.add_with_priority(v, dist[v]) while Q is not empty: // The main loop u ← Q.extract_min() // Remove and return best vertex for each neighbor v of u: // only v that are still in Q alt ← dist[u] + length(u, v) if alt < dist[v] dist[v] ← alt prev[v] ← u Q.decrease_priority(v, alt) return dist, prev
Code :
// single source shortest path // no negative edges #include <bits/stdc++.h> using namespace std; #define adjacency_list map<int, vector<pair<int, int>>> #define mp make_pair #define INF INT_MAX typedef struct graph { adjacency_list adj; int num_edges; int num_vertices; } graph; void dijkstra(graph G, int source) { set<int> vertex_set; for (int i = 0; i < G.num_vertices; i++) { vertex_set.insert(i); } vector<int> dist(G.num_vertices, INF); vector<int> prev(G.num_vertices, -1); dist[source] = 0; while (!vertex_set.empty()) { int u = *(vertex_set.begin()); int min_dist = INF; for (auto i : vertex_set) { if (dist[i] < min_dist) { u = i; min_dist = dist[i]; } } vertex_set.erase(u); // u has vertex with min distance from source // terminate dijkstra if you want minimum distance to this vertex. for (auto i : G.adj[u]) { int v = i.first; if (dist[u] != INF && dist[u] + i.second < dist[v]) { dist[v] = dist[u] + i.second; prev[v] = u; } } } cout << "vertex prev dist\n"; for (int i = 0; i < G.num_vertices; i++) { cout << i << " " << prev[i] << " " << dist[i] << "\n"; } // cout << "\n"; } int main() { // undirected graph graph G; // u - {{v1,w1}, {v2, w2}, .... {vk,wk}} cin >> G.num_vertices; cin >> G.num_edges; int u, v, w; for (int i = 0; i < G.num_edges; i++) { cin >> u >> v >> w; G.adj[u].push_back(mp(v, w)); G.adj[v].push_back(mp(u, w)); // comment this if directed. } int s; // cout << "Enter start vertext for dijkstra : "; cin >> s; dijkstra(G, s); // cout << "\n"; }
Complexity Analysis :
Time complexity : \(O(|V|^2)\) . This is the original dijkstra's algorithm which does not use min-heap to get min distance.
Try using min heap in the above implementation.
Complexity dependends on the implementation of this algorithm. \(O(|E|T_{decrease\_key}+|V|T_{extract\_min})\)