Skip to content
DSA graphs 8 min read

Dijkstra's Algorithm: Shortest Path with a Priority Queue

Dijkstra’s algorithm finds the shortest path from one source vertex to every other vertex in a weighted graph with non-negative edge weights. It greedily settles the closest unsettled vertex, then relaxes its edges — updating a neighbor’s distance if going through the current vertex is cheaper. With a priority queue (min-heap) it runs in O((V + E) log V).

How it works

  1. Set dist[source] = 0 and every other distance to infinity.
  2. Push (0, source) into a min-heap keyed by distance.
  3. Pop the vertex u with the smallest tentative distance. If it’s stale (the popped distance is larger than the recorded one), skip it.
  4. Relax each edge u → v: if dist[u] + weight < dist[v], update dist[v] and push (dist[v], v).
  5. Repeat until the heap is empty. The first time a vertex is popped, its distance is final.
#include <vector>
#include <queue>
#include <climits>

// graph[u] = list of (neighbor, weight)
std::vector<long long> dijkstra(
        const std::vector<std::vector<std::pair<int,int>>>& graph, int src) {
    int n = graph.size();
    const long long INF = LLONG_MAX;
    std::vector<long long> dist(n, INF);
    using P = std::pair<long long,int>;            // (distance, vertex)
    std::priority_queue<P, std::vector<P>, std::greater<P>> pq;
    dist[src] = 0;
    pq.push({0, src});
    while (!pq.empty()) {
        auto [d, u] = pq.top(); pq.pop();
        if (d > dist[u]) continue;                 // stale entry, skip
        for (auto [v, w] : graph[u]) {
            if (dist[u] + w < dist[v]) {           // relaxation
                dist[v] = dist[u] + w;
                pq.push({dist[v], v});
            }
        }
    }
    return dist;
}

Pitfall: The if (d > dist[u]) continue; “stale check” is essential. Lazy-deletion heaps keep outdated entries; without skipping them you re-process vertices and the running time degrades. Equally important: Dijkstra is wrong with negative edges — a later cheaper path can appear after a vertex is settled. For negative weights use Bellman-Ford.

Reconstructing the path

Keep a parent array; whenever you relax u → v, set parent[v] = u. Then walk parent back from the target to the source and reverse it.

Complexity

  • Time: O((V + E) log V) with a binary heap.
  • Space: O(V + E) for the graph plus O(V) for distances and the heap.

When to use Dijkstra

Use it for single-source shortest paths on graphs with non-negative weights — road networks, latency-weighted routing, game pathfinding. Need negative weights or negative-cycle detection? See Bellman-Ford. Need all pairs at once on a small graph? See Floyd-Warshall.

Last updated June 25, 2026
Was this helpful?