Bellman-Ford Algorithm
Table of Contents + β
Say you are booking a trip. You start from one city. You want the cheapest way to reach every other city. Some routes even pay you back, like a cashback offer. So the cost on that step is negative. The popular shortest-path algorithm, Dijkstra, breaks here. It assumes no route ever pays you back. So when costs can go negative, we need a different tool. That tool is the Bellman-Ford algorithm.
π What Is Bellman-Ford?
Bellman-Ford finds the shortest path from one starting vertex to every other vertex in a weighted graph. A shortest path here means the path with the smallest total weight. It is not about the fewest hops.
The thing that makes it special:
- It works even when some edges have negative weights. A negative weight just means that step lowers your total cost.
- It can tell you when the graph has a negative cycle. A negative cycle is a loop you can go around again and again, lowering your cost with no end. When that happens, no real shortest path exists.
Dijkstra cannot do either of those. Bellman-Ford is slower, but it gives correct answers on graphs Dijkstra cannot handle.
Note
A βsourceβ is just the vertex you start from. Single-source shortest path means we compute the distance from that one source to all the others in one run.
π A Real-World Way to Picture It
Think of currency exchange. You have rupees and you want dollars. There are many ways to convert. You can go rupees to euros to dollars. Or you can go rupees straight to dollars. Each hop has a cost. Some hops, because of a good rate, leave you with more value. That is a negative cost.
Now imagine a loop. You convert rupees to euros, then to pounds, then back to rupees. And you end up with more money than you started with. You could go around that loop forever and keep gaining value with no end. That broken loop is a negative cycle. Bellman-Ford spots this and says βstop, there is no sane answer here.β
π― The Core Idea: Relaxation
The whole algorithm rests on one small move. It is called relaxation. Relaxing an edge means one simple thing. You check if going through this edge gives a cheaper way to reach a vertex. If it does, you update the cost.
Here is the rule for an edge from u to v with weight w:
- If
dist[u] + wis smaller thandist[v], then we found a cheaper path. So setdist[v] = dist[u] + w. - Otherwise, leave it alone.
We start by setting the source distance to 0 and every other distance to infinity. Infinity means βnot reachable yetβ. Then we relax edges again and again until nothing improves.
Tip
βInfinityβ in code is just a very large number that stands for βwe have no path here yetβ. Any real path will be smaller than it.
π Why Relax V-1 Times?
Now think about how long a shortest path can get. In a graph with V vertices, the longest a shortest path can ever be is V-1 edges. Why? Because a shortest path never repeats a vertex. If it did, it would contain a loop. And removing that loop would make it shorter or equal. So with V vertices, you can touch at most V of them. That is V-1 edges between them.
So we do this:
- Pass 1 settles all shortest paths that use 1 edge.
- Pass 2 settles all shortest paths that use up to 2 edges.
- And so on, up to pass
V-1.
After V-1 passes, every real shortest path is final. That is why we loop V-1 times.
Now the negative-cycle check. After V-1 passes everything should be settled. So we run one more pass. If any edge can still be relaxed, that means costs keep dropping with no bottom. That can only happen if a negative cycle exists.
Caution
The extra pass does not fix anything. It is only a test. If even one edge improves on that final pass, you report a negative cycle and you stop using the distances.
πΊοΈ A Small Example Graph
Letβs use a tiny graph with four vertices: 0, 1, 2, 3. Vertex 0 is our source. Notice the negative edge from 2 to 1.
Letβs trace it by hand. We start with dist[0] = 0 and the rest as infinity.
| Vertex | Start | After relaxing | How we got there |
|---|---|---|---|
| 0 | 0 | 0 | source |
| 1 | infinity | 2 | 0 to 2 to 1 (5 + -3) |
| 2 | infinity | 5 | 0 to 2 (5) |
| 3 | infinity | 5 | 0 to 2 to 1 to 3 (5 + -3 + 3) |
See how reaching 1 directly costs 4, but going 0 to 2 to 1 costs only 2? That is because of the negative edge. Dijkstra would have locked in the 4 too early and missed this. Bellman-Ford keeps relaxing, so it catches it.
πͺ Steps to Run Bellman-Ford
Here is the full recipe, in order:
- Set
dist[source] = 0anddist[v] = infinityfor every other vertex. - Repeat
V-1times: go through every edge(u, v, w)and relax it. - Do one final pass over all edges. If any edge can still be relaxed, report a negative cycle.
- If no edge improves on that final pass, the
distarray holds the real shortest distances.
Notice that each pass touches every edge in the graph. The order you visit them does not change the final answer.
π» Bellman-Ford in Code
Now letβs turn that recipe into a program. We store the graph as a simple list of edges, where each edge is (u, v, w). We run the relaxation passes. Then we do the one extra check for a negative cycle. Finally we print the distances from source 0.
def bellman_ford(edges, V, source): # Step 1: every distance is infinity, source is 0 dist = [float("inf")] * V dist[source] = 0
# Step 2: relax all edges V-1 times for _ in range(V - 1): for u, v, w in edges: if dist[u] != float("inf") and dist[u] + w < dist[v]: dist[v] = dist[u] + w
# Step 3: one more pass to detect a negative cycle for u, v, w in edges: if dist[u] != float("inf") and dist[u] + w < dist[v]: print("Negative cycle detected") return
# Step 4: print the shortest distances for i in range(V): print(f"Distance to {i} = {dist[i]}")
# edges as (u, v, w)graph = [(0, 1, 4), (0, 2, 5), (2, 1, -3), (1, 3, 3), (2, 3, 2)]bellman_ford(graph, 4, 0)The output of the above code will be:
Distance to 0 = 0Distance to 1 = 2Distance to 2 = 5Distance to 3 = 5Look at the distance to vertex 1. It came out as 2, not 4. That is the negative edge from 2 to 1 lowering the cost. Bellman-Ford caught it because it kept relaxing.
β±οΈ How Slow Is It?
We loop V-1 times. Inside each loop we touch every edge E. So the work is roughly V times E.
Note
The time complexity is O(V * E). Space is O(V) because we only keep one distance value per vertex.
For dense graphs, where E can be close to V squared, this becomes about O(V^3). That is the price you pay for handling negative edges.
βοΈ Bellman-Ford vs Dijkstra
Both find single-source shortest paths. So when do you reach for which one? Here is the honest comparison.
| Point | Bellman-Ford | Dijkstra |
|---|---|---|
| Negative edges | Handles them | Cannot handle them |
| Negative cycle | Detects it | No detection |
| Time complexity | O(V * E) | O((V + E) log V) |
| Speed in practice | Slower | Faster |
| Best when | Weights can be negative | All weights are zero or positive |
The short version: if every weight is positive, use Dijkstra because it is faster. The moment a negative weight shows up, switch to Bellman-Ford.
β οΈ Common Mistakes
A few traps students fall into:
- Stopping after one pass. You must repeat the relaxation
V-1times, not just once. - Skipping the extra pass. Without that final check you never find out about a negative cycle, and your distances are quietly wrong.
- Adding weight to an βinfinityβ distance. If
dist[u]is still infinity, that vertex is not reachable yet, so do not relax from it. Notice every code sample checks for this first. - Using Dijkstra on a graph with negative edges. It runs, it gives an answer, but the answer is wrong. And a wrong answer that looks fine is very hard to catch.
π§© What Youβve Learned
β Bellman-Ford finds shortest paths from one source to all vertices, even with negative edge weights.
β
Relaxation is the one core move: if dist[u] + w beats dist[v], update dist[v].
β
We relax every edge V-1 times because a shortest path has at most V-1 edges.
β One extra pass that still improves means there is a negative cycle, so no valid shortest path exists.
β
The time complexity is O(V * E), slower than Dijkstra but able to handle negative weights.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
Why does Bellman-Ford relax every edge exactly V-1 times?
Why: A shortest path never repeats a vertex, so with V vertices it can span at most V-1 edges.
- 2
What does it mean if an edge can still be relaxed on the extra pass after V-1 passes?
Why: If costs keep dropping after V-1 passes, there is a loop that lowers cost forever, which is a negative cycle.
- 3
What is the main advantage of Bellman-Ford over Dijkstra?
Why: Dijkstra fails with negative weights, while Bellman-Ford handles them and can flag negative cycles.
- 4
What is the time complexity of Bellman-Ford?
Why: It relaxes all E edges across V-1 passes, giving O(V * E).