Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Bellman-Ford Shortest Paths

What It Solves & When

Single-source shortest paths that tolerate negative edges — when do you need this instead of Dijkstra?

Core Idea: Relax Every Edge, Repeatedly

Why does relaxing all edges V-1 times guarantee correct distances? What does each pass “settle”?

One Pass = One Edge of Path Length

After pass k, which shortest paths are guaranteed correct? Think in terms of hop count.

Why V-1 Passes Suffice

A simple shortest path has at most V-1 edges. How does that fact cap the number of passes you need?

The Dynamic-Programming View

Frame dist as “cheapest path using at most k edges.” What’s the recurrence relating the k-edge answer to the (k-1)-edge answer?

The Relaxation Loop

What’s the exact structure — repeated passes over the full edge list — and how does dist[] evolve pass to pass?

Order of Edge Processing

Why can a lucky edge order finalize distances faster, yet the worst case still needs all V-1 passes?

Detecting Negative Cycles

What happens on a V-th pass if any edge still relaxes? Why does that prove a negative cycle is reachable from the source?

Reporting the Cycle

How do you recover the actual vertices on the negative cycle, not just a yes/no? What does following predecessors give you?

Early Termination

If a full pass makes no updates, what can you conclude and stop?

Why It Doesn’t Need a Priority Queue

Dijkstra needs ordering; Bellman-Ford brute-forces edges. What does it trade away to gain negative-edge support?

Variants

SPFA (queue-based relaxation); use as a subroutine inside Johnson’s; DAG shortest paths via topological order in one pass — how do these relate?

vs Dijkstra

Generality vs speed. Which to pick when all weights are non-negative, and why?

Time Complexity

Each pass scans all E edges, and there are up to V-1 passes. How does that product give the bound, and how does early termination affect the best case?

Where the V·E Comes From

Walk the two nested loops — passes over vertices, edges within each pass. Why is each factor exactly what it is?

Space Complexity

What do you store beyond the edge list — dist[], prev[]? How does using an edge list rather than adjacency lists affect the space picture?

Implementation Walkthrough

Plan the code before writing it.

Graph & Structures Setup

Why is a flat edge list (u, v, w) convenient here? How do you initialize dist[] and prev[]?

The Relaxation Passes

Sketch the outer V-1 loop wrapping an inner sweep over every edge. What does a single relaxation update?

The Negative-Cycle Check

What extra pass do you run after the main loop, and what does any successful relaxation in it signal?

Reconstruction

How do you rebuild a path from prev[], and how do you report “unreachable” vs “affected by a negative cycle”?

Real Uses

Currency arbitrage detection, distance-vector routing protocols — why do negative weights show up there?

Pitfalls

Stopping at V passes instead of V-1; mishandling unreachable vertices; integer overflow on INF + weight — how do you guard each?

Implementation

// implement from scratch here

Summary

Recap the whole topic in a few lines — the core idea, the key complexities and trade-offs, and when to reach for it. The cheat-sheet you’d skim before an exam or interview.

My Notes

Fill this in as you learn