3.5.11 · D5Graphs

Question bank — Bellman-Ford algorithm — DP approach, negative cycles detection, O(VE)

2,168 words10 min readBack to topic

Before we start, here is a fully self-contained refresher — the whole algorithm plus its vocabulary — so no question below forces you to click away.

The figures below show what "relaxation," "pass-by-pass convergence," and "detection" actually look like — glance at them before diving into the traps.

Edge relaxation, one step:

Figure — Bellman-Ford algorithm — DP approach, negative cycles detection, O(VE)

Pass-by-pass convergence on a small graph:

Figure — Bellman-Ford algorithm — DP approach, negative cycles detection, O(VE)

Why the extra pass catches a negative cycle:

Figure — Bellman-Ford algorithm — DP approach, negative cycles detection, O(VE)


True or false — justify

Every answer explains why, never a bare verdict.

Bellman-Ford needs exactly passes to always be correct on a graph with no negative cycle.
True. A simple shortest path visits at most vertices, so it uses at most edges; each pass "locks in" at least one more edge of that path, so passes suffice.
If a pass makes no updates, the algorithm can stop early even if fewer than passes have run.
True. No update means every dist[] value already satisfies all relaxation conditions, so further passes cannot change anything — that is the early-exit optimization (the if not updated: break line).
Running passes instead of gives more accurate distances.
False. Distances converge by pass ; the -th pass only detects negative cycles. If it changes a distance, that value is inside a negative cycle and is meaningless, not "more accurate."
Bellman-Ford can compute shortest paths on a graph that contains a negative cycle unreachable from the source.
True. Only cycles reachable from corrupt distances. An unreachable negative cycle never touches any relaxed dist[] value, so the answers for reachable nodes stay correct.
Bellman-Ford finds every negative cycle in the graph.
False. It only reports negative cycles reachable from the source . A negative cycle in a disconnected part stays invisible unless you add a virtual source with -weight edges to all vertices.
The final distance array does not depend on the order in which edges are relaxed within a pass.
True for the final result after passes; the intermediate per-pass values do depend on order, but convergence to the same answer is guaranteed.
Bellman-Ford works on undirected graphs with a single negative edge.
False (in general). An undirected negative edge is really two directed edges and of the same negative weight — together they form a negative cycle of length 2, which Bellman-Ford will flag.
Dijkstra could replace Bellman-Ford if we just add a big constant to every edge weight to make them non-negative.
False. Adding a constant to each edge penalizes paths by , so it changes which path is shortest. Longer-hop paths get unfairly inflated; the answers become wrong. (Dijkstra's greedy "finalize the closest node" trick — see Dijkstra's Algorithm — needs the original non-negative weights, not doctored ones.)
The dist[u] != inf guard changes which final distances Bellman-Ford produces.
False in exact arithmetic — inf + w stays inf, so relaxing from an unreachable node never helps. The guard exists to avoid overflow in fixed-width integers and spurious "updates," not to change correctness.
If the graph is a DAG (no cycles at all), Bellman-Ford can never report a negative cycle.
True. A negative cycle is a cycle; a DAG has none by definition, so the extra pass can never find an improving edge. (A topological-order relaxation would be faster here, but Bellman-Ford is still correct.)

Spot the error

Each line describes a buggy claim or code idea; the reveal names the exact flaw.

"I return dist immediately after passes without the extra pass."
You lose negative-cycle detection. If a reachable negative cycle exists, the returned distances are finite garbage instead of a "no shortest path" flag.
"I do the detection pass, and if an edge relaxes I set dist[v] to the new smaller value and continue."
Wrong: once you know a negative cycle exists, distances are undefined. You should report the cycle (return None/flag), not keep shrinking values that will never stabilize.
"I only run the detection pass over edges I updated in pass ."
Buggy. A negative cycle may only reveal itself through an edge you did not touch last pass; the detection pass must scan all edges.
"I initialize dist[src] = 0 and everything else to 0 too."
Wrong base case. Non-source nodes must start at , meaning "unknown / unreachable so far." Starting at pretends every node is free to reach and corrupts all relaxations.
"I break out of the loop the first time any single edge cannot be improved (its relax check is false)."
Wrong condition. You break only when an entire pass improves nothing. A single edge whose dist[u]+w < dist[v] check fails says nothing; other edges in the same pass may still improve — that is why the code tracks an updated flag over the whole sweep.
"To speed things up I relax each edge only if its endpoint changed last pass — that's the whole optimization."
That describes SPFA, a queue-based refinement that only re-processes vertices whose distance just dropped. It is a valid optimization but it is not plain Bellman-Ford, and its worst case is still ; do not claim it changes the guarantee.
"For an all-pairs shortest path I run Bellman-Ford once and read off all distances."
Error: one Bellman-Ford run is single-source — distances from one only. For all pairs, run it times (once per source) or use Floyd-Warshall, which computes every pair in .
"My graph has a positive cycle, so the extra pass will falsely report a negative cycle."
False alarm about a false alarm. A positive (or zero) cycle never lowers a distance, so the detection pass finds no improving edge and correctly reports "no negative cycle."

Why questions

Why is the loop bounded by and not by (the number of edges)?
Because the bound comes from path length, not edge count. A simple shortest path has at most edges regardless of how many edges the graph has, so passes always suffice.
Why does one successful relax in the -th pass prove a negative cycle exists?
After passes every simple path is fully accounted for, so nothing simple can improve. Any further improvement must come from re-visiting a vertex — a cycle — and only a negative cycle lowers the total, so an improving edge is a certificate of one.
Why does Bellman-Ford make "no greedy commitment," unlike Dijkstra?
Dijkstra permanently finalizes the closest unfinished node, trusting that no future path beats it — valid only for non-negative edges. Bellman-Ford never finalizes; it keeps re-relaxing every edge, so a later negative edge can still rescue a distance.
Why is Bellman-Ford considered Dynamic Programming rather than greedy?
Its state = shortest distance to using at most edges, built from via a recurrence. It solves overlapping subproblems bottom-up over the number of edges — the definition of DP.
Why does adding a "virtual source" connected to every vertex with -weight edges let us detect all negative cycles?
The virtual source makes every vertex reachable, so every negative cycle is now reachable from a single source. One Bellman-Ford run from the virtual source then flags any negative cycle in the whole graph, connected or not.
Why must we guard relaxation with dist[u] != inf?
An unreachable has dist[u] = inf. In integer arithmetic inf + w can overflow to a negative-looking number, which would fake an improvement and corrupt dist[v]. The guard skips these impossible relaxations.
Why is the time complexity and not ?
We do up to passes, and each pass relaxes all edges once: work. It is written in terms of because a graph can have anywhere from to edges.

Edge cases

Single vertex, no edges, source = that vertex.
dist = [0]. With we run relaxation passes; the base case is already the final answer. The detection pass finds nothing.
Source cannot reach some vertex .
dist[t] stays forever — correct. "Unreachable" is faithfully represented by an unchanged infinite distance, and the guard keeps us from ever relaxing out of it.
A graph with a self-loop of weight .
This is a negative cycle of length 1. If is reachable, the detection pass relaxes the self-loop endlessly and correctly reports a negative cycle.
A graph with a self-loop of weight .
Harmless. A positive self-loop never improves dist[v], so it is silently ignored and never triggers detection.
Two vertices with edges and for the same .
The round trip sums to : a zero-weight cycle, not negative. Distances converge normally and no cycle is reported — negativity, strictly less than zero, is what matters.
All edge weights are non-negative.
Bellman-Ford still produces the correct answer, just slower than Dijkstra's Algorithm. There can be no negative cycle, so the detection pass always passes clean.
The shortest path genuinely uses all edges (a long chain).
This is the worst case that requires every one of the passes. With an unlucky edge order, each pass may extend the frontier by only one edge, so you cannot safely stop early.
Empty edge list but .
Only the source has a finite distance (); all others stay . No edge means nothing to relax and nothing to detect — trivially correct.

Recall One-question self-audit

Cover the reveals above. If you can restate why the -th pass computes nothing but only detects, and why only reachable cycles are found, you have understood the two ideas this bank keeps circling. This is one corner of the broader Shortest Path Problem.

Connections