Bellman-Ford algorithm — DP approach, negative cycles detection, O(VE)
WHAT is Bellman-Ford?
WHY do we need it (when Dijkstra exists)? Dijkstra assumes once you "finalize" a node, no future path can beat it — true only if all edges are . A negative edge can make a longer-hop path cheaper later, breaking Dijkstra's greedy promise. Bellman-Ford makes no greedy commitment; it just keeps relaxing until nothing improves.
HOW: the DP derivation from scratch
Let me derive it, not memorize it.
Define the subproblem:
Base case (WHY): with edges you can only stay at .
Transition (WHY): a path to using edges either:
- uses edges (don't add anything), or
- takes a path to some neighbor in edges, then the edge .
WHY stop at ? A shortest path with no negative cycle is simple (no repeated vertex), so it has at most vertices and hence at most edges. So is the true answer.
Relaxation = the transition in disguise
We don't need the 2D table. Keep one array dist[] and "relax":
relax(u, v, w): if dist[u] + w < dist[v]: dist[v] = dist[u] + w
Running one full pass over all edges = advancing by (at least) one. Doing passes guarantees convergence.

HOW: negative cycle detection
Pseudocode (full)
def bellman_ford(V, edges, src):
dist = [float('inf')] * V
dist[src] = 0
# V-1 relaxation passes
for _ in range(V - 1):
updated = False
for u, v, w in edges:
if dist[u] != float('inf') and dist[u] + w < dist[v]:
dist[v] = dist[u] + w
updated = True
if not updated: # early exit optimization
break
# one extra pass -> detect negative cycle
for u, v, w in edges:
if dist[u] != float('inf') and dist[u] + w < dist[v]:
return None # negative cycle reachable
return distWhy the dist[u] != inf guard? inf + w is still inf; without the guard you'd never wrongly relax, but it avoids spurious updates and overflow in languages with fixed-width ints.
Worked Example 1 — normal graph with a negative edge
Vertices ; edges: . Source .
| pass | dist[0] | dist[1] | dist[2] | dist[3] |
|---|---|---|---|---|
| init | 0 | ∞ | ∞ | ∞ |
| 1 | 0 | 4 | 1 (via 1→2, ) | 3 |
| 2 | 0 | 4 | 1 | 3 |
- Why does pass 1 give dist[2]=1 not 5? Order matters: we relaxed first (dist[1]=4), then used it → , beating the direct .
- Why does pass 2 change nothing? Already converged; the early-exit
breaktriggers. passes weren't all needed.
Answer: .
Worked Example 2 — negative cycle
Edges: . Source .
Cycle has weight .
- After passes, dist keeps dropping.
- Why detection fires: the extra pass still relaxes some edge (e.g. improves dist[0]). → report negative cycle.
Why this step matters: distances are meaningless here, so we must return a flag, not numbers.
Common mistakes
Recall Feynman: explain to a 12-year-old
Imagine prices to travel between cities, where some roads pay you (negative cost). You want the cheapest way from home to every city. You go around updating "cheapest known cost so far" by checking every road again and again. After checking the whole map (number of cities − 1) times, the prices stop dropping — that's your answer. But if there's a loop of roads that pays you net money each lap, your cost never stops dropping (free money forever!). So if one more full check still lowers a price, you shout "there's a money-loop!" — that's a negative cycle.
Recall checks
Flashcards
Bellman-Ford time complexity
Bellman-Ford DP subproblem
Why relax times
Bellman-Ford transition
How to detect a negative cycle
Which negative cycles does it detect
Why Dijkstra fails with negative edges
Base case of Bellman-Ford DP
Early-exit optimization
Trick to detect ALL negative cycles
Connections
- Dijkstra's Algorithm — faster () but needs non-negative edges
- Dynamic Programming — Bellman-Ford is DP over "edges used"
- Floyd-Warshall — all-pairs version, also handles negatives,
- Shortest Path Problem
- Negative Weight Cycles
- Graph Relaxation
- SPFA — queue-based optimization of Bellman-Ford
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Bellman-Ford ka idea simple hai: shortest path mein agar koi negative cycle nahi hai, to woh ek "simple path" hoga, yaani usme zyada se zyada edges honge. Isliye agar hum saare edges ko baar "relax" kar dein (relax matlab: agar dist[u]+w se dist[v] chhota ho jaaye to update kar do), to har node ki sahi shortest distance mil jaati hai. Yahi reason hai complexity ka — passes, har pass mein edges.
Dijkstra negative edges pe fail karta hai kyunki woh greedy hai — ek baar node finalize kar diya to maan leta hai ki future mein koi sasta raasta nahi aayega. Lekin negative edge baad mein ek lamba raasta sasta bana sakta hai. Bellman-Ford koi greedy commitment nahi karta, bas baar-baar relax karta rehta hai, isliye negative weights handle kar leta hai.
Negative cycle detection ka jugaad mast hai: passes ke baad sab kuch settle ho jaana chahiye. Ab agar ek extra pass mein bhi koi edge relax ho raha hai, iska matlab koi cycle hai jiska total weight negative hai — usme ghoom-ghoom ke distance infinite tak girta rahega, to finite shortest path exist hi nahi karta. Yaad rakhna: yeh sirf woh negative cycles pakadta hai jo source se reachable hain.
Formula yaad rakhne ka tareeka: "V-minus-one to relax, one more to react." Pehle passes distances nikaalte hain, aur last wala +1 pass sirf negative cycle ko react/detect karne ke liye hai. Exam aur interview dono mein yeh point bahut poocha jaata hai.