Dijkstra's Algorithm

Concept

Dijkstra's algorithm finds the shortest path from a source node to all other nodes in a weighted graph with non-negative edge weights. It greedily picks the closest unvisited node and relaxes its neighbors.

When to Use

  • Shortest path in a weighted graph with non-negative weights
  • Single-source shortest path (SSSP) problems
  • Finding minimum cost to reach every node from a starting point
  • Problems like 'minimum time/cost to travel from A to B'

Intuition

Imagine you're at a city and want to find the fastest route to every other city. You always expand from the closest city you haven't visited yet. Once you visit a city, you know its shortest distance for sure — because any other path would go through a farther city first, which can't be shorter. The min-heap (priority queue) efficiently gives us the "closest unvisited" node.

Complexity

Time
O((V + E) log V)
Space
O(V + E)

Template Code

cpp
#include<bits/stdc++.h>
using namespace std;

int main(){
    ios_base::sync_with_stdio(0), cin.tie(0);

    int n, m;
    cin >> n >> m;

    vector<vector<pair<int, int>>> adj(n);

    int a, b, w;
    for(int i = 0; i < m; i++){
        cin >> a >> b >> w;
        adj[a].push_back({b, w});
        adj[b].push_back({a, w});
    }

    const int inf = 1e9+7;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    vector<int> dist(n, inf);

    pq.push({0, 3});
    dist[3] = 0;

    while(!pq.empty()){
        int w = pq.top().first;
        int v = pq.top().second;
        pq.pop();

        for(auto &u : adj[v]){
            if(w+u.second < dist[u.first]){
                pq.push({w+u.second, u.first});
                dist[u.first] = w+u.second;
            }
        }
    }

    for(int x : dist){
        cout << x << " ";
    }

    return 0;
}

// Sample Input:
// 5 7
// 0 1 2
// 0 4 3
// 1 2 4
// 1 3 7
// 2 4 1
// 3 4 2
// 2 3 1
//
// Sample Output (from node 3):
// 5 7 3 0 2