3.5.10Graphs

Dijkstra's algorithm — greedy, priority queue, O((V+E) log V) — no negative edges

1,810 words8 min readdifficulty · medium6 backlinks

Single-source shortest paths in a graph with non-negative edge weights.


WHAT is the problem?

We keep an array dist[]dist[] where dist[v]dist[v] is our current best known distance. It starts as \infty for everyone except dist[s]=0dist[s]=0, and we shrink it as we discover shorter routes (relaxation).


WHY does greedy work? (the key derivation)

Claim (the invariant we must prove): When we pop the vertex uu with the smallest tentative distance from the frontier, dist[u]dist[u] is already the true shortest distance.


HOW: the algorithm

dijkstra(G, s):
    dist[v] = INF for all v;  dist[s] = 0
    PQ = min-heap with (0, s)
    while PQ not empty:
        (d, u) = PQ.pop_min()
        if d > dist[u]: continue        # stale entry, skip
        for each edge (u, v, w):
            if dist[u] + w < dist[v]:
                dist[v] = dist[u] + w
                PQ.push((dist[v], v))    # lazy: leaves old entry behind
    return dist
Figure — Dijkstra's algorithm — greedy, priority queue, O((V+E) log V) — no negative edges

Complexity — derived, not memorized

Each edge can trigger at most one push (one per successful relaxation), so the heap holds at most O(E)O(E) entries.

  • Pops: at most O(E)O(E) pops, each O(logV)O(\log V) (heap size is EV2\le E \le V^2, and logV2=2logV\log V^2 = 2\log V).
  • Pushes: at most O(E)O(E), each O(logV)O(\log V).
  • Initialization: O(V)O(V).

Worked example

Graph (directed): A→B(4), A→C(1), C→B(2), C→D(5), B→D(1), source A.

Step Pop dist updates dist after
init A=0A=0 A0 B∞ C∞ D∞
1 A(0) C: 0+1=1, B: 0+4=4 A0 B4 C1 D∞
2 C(1) B: 1+2=3<4 ✓, D: 1+5=6 A0 B3 C1 D6
3 B(3) D: 3+1=4<6 ✓ A0 B3 C1 D4
4 D(4) none done

Why pop C before B? After step 1, the heap has B(4) and C(1). We pop the minimum, C. This greedy order is what guarantees correctness — and it's why C's relaxation later improves B from 4 to 3.



Recall Feynman: explain to a 12-year-old

You're at home and want the fastest time to reach every house in town. You start a timer. Roads take different minutes to walk. You keep a "best time so far" sticky note on each house. You always go to the nearest house you haven't finalized yet, because once you reach it the fast way, no slower house can give you a shortcut (all roads cost positive time — there's no magic road that gives back minutes). You stamp it "done" and update its neighbors' sticky notes. Repeat. The priority queue is just a smart way to always grab the nearest not-done house quickly.


Flashcards

What problem does Dijkstra solve?
Single-source shortest paths from a source ss to all vertices in a graph with non-negative edge weights.
What is "relaxation"?
Updating dist[v]=min(dist[v],dist[u]+w(u,v))dist[v]=\min(dist[v],\,dist[u]+w(u,v)) when going through uu is cheaper.
Why does Dijkstra require non-negative edges?
The correctness proof uses "the rest of the path has weight ≥ 0" so the popped min-distance vertex is already final; negative edges break this since a longer path could become cheaper.
When is a vertex's distance finalized?
When it is popped from the priority queue with a non-stale distance (not when it is pushed/relaxed).
What is the time complexity with a binary heap?
O((V+E)logV)O((V+E)\log V).
What complexity does a Fibonacci heap give?
O(E+VlogV)O(E + V\log V) via amortized O(1)O(1) decrease-key.
What does the line if d > dist[u]: continue do?
Skips stale heap entries in the lazy-deletion approach (a vertex pushed multiple times; only its first/best pop matters).
Which algorithm to use for negative edges?
Bellman-Ford, O(VE)O(VE) (or Johnson's for all-pairs).
Which algorithm for unweighted shortest path?
BFS, O(V+E)O(V+E) — no heap needed.
In the greedy invariant proof, what is yy?
The first unfinalized vertex on the true shortest path to uu; already relaxed via finalized predecessor xx.

Connections

  • Bellman-Ford algorithm — handles negative edges, O(VE)O(VE)
  • BFS — Dijkstra reduces to BFS when all weights equal 1
  • A* search — Dijkstra + admissible heuristic
  • Priority Queue (Binary Heap) — the engine behind the logV\log V
  • Greedy algorithms — why exchange/invariant arguments justify greed
  • Prim's algorithm — same heap-driven skeleton, different relaxation (MST not SSSP)
  • Johnson's algorithm — reweighting to run Dijkstra on negative-edge graphs

Concept Map

solved by

maintains

updated by

picks closest via

pops min

guaranteed by

proven using

removing breaks

lazy deletion

gives

shrinks

SSSP Problem

Dijkstra Greedy

dist array

Relaxation Rule

Min-Heap Priority Queue

Finalize Vertex

Invariant: dist is true

Non-Negative Edges

Fails on Negative Edges

Skip Stale Entries

O of V+E log V

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dijkstra ka basic idea simple hai: source se paani chhodo, jo city pehle reach hoti hai uska shortest distance utna hi final ho gaya. Hum ek dist[] array rakhte hain — shuru me sab infinity, source ka 0. Phir priority queue (min-heap) se hamesha sabse closest unfinalized vertex nikalte hain, use "done" mark karte hain, aur uske neighbours ko relax karte hain: agar dist[u] + w < dist[v] ho to update kar do.

Greedy kyun chalta hai? Kyunki edges non-negative hain. Jab tum minimum distance wala vertex pop karte ho, koi bhi lamba raasta use sasta nahi bana sakta — kyunki extra edges sirf weight badhayenge, ghatayenge nahi. Yahi reason hai ki negative edge aate hi Dijkstra galat ho jata hai (tab Bellman-Ford use karo). Proof me bas ek hi jagah "≥ 0" use hota hai — wahi sab kuch hold karta hai.

Code me ek important trick hai: lazy heap. Decrease-key ki jagah hum naya (new_dist, v) push kar dete hain, purana stale entry heap me reh jata hai. Isliye if d > dist[u]: continue line lagao — stale pop ko skip karne ke liye. Vertex tab finalize hota hai jab pop hota hai, push pe nahi.

Complexity: har edge ek push de sakta hai, to heap me O(E)O(E) entries, har operation O(logV)O(\log V), total O((V+E)logV)O((V+E)\log V). Fibonacci heap se O(E+VlogV)O(E + V\log V). Exam aur interview dono me yeh standard answer hai — yaad rakho aur derive bhi kar pao.

Go deeper — visual, from zero

Test yourself — Graphs

Connections