Articles

Bellman-Ford vs Dijkstra's Algorithm, Explained

Bellman-Ford handles negative edge weights and detects negative cycles; Dijkstra is faster but can't. When to use each shortest-path algorithm.

The Lycoris Team The Lycoris Team · · 4 min read
A chalkboard filled with graph diagrams and equations

Bellman-Ford and Dijkstra’s algorithm both find the shortest path from a starting node to every other node in a weighted graph, but they make opposite tradeoffs to get there. Dijkstra is fast but assumes every edge weight is non-negative. Bellman-Ford is slower but works correctly even when some edges subtract from the path’s total weight — and it can detect when that flexibility creates a problem with no valid answer at all.

Why negative weights break Dijkstra

Dijkstra’s algorithm works by repeatedly picking the unvisited node with the smallest known distance, finalizing that distance, and relaxing (updating) the distances of its neighbors. The correctness of that approach depends on one assumption: once a node’s shortest distance is finalized, no later discovery can make it shorter. That’s only true if every edge weight is non-negative — if edges can be negative, a path discovered later, through a node that looked farther away, could still end up cheaper overall.

A negative edge weight isn’t just a theoretical curiosity. It shows up naturally whenever a graph models something other than pure distance — a financial model where a transaction can free up value elsewhere, a network where certain hops in a routing protocol are being deliberately discounted, or an arbitrage-detection graph where an edge weight represents a currency conversion’s log-rate, and profitable cycles are exactly what you’re trying to find. In any of these, Dijkstra will silently produce a wrong answer rather than an error.

How Bellman-Ford handles it

Bellman-Ford takes a much simpler, brute-force approach: relax every edge in the graph, repeat that for V - 1 iterations (where V is the number of nodes), and after that many passes, every shortest path is guaranteed to be found — because the longest possible shortest path, without revisiting a node, touches at most V - 1 edges. There’s no need to pick the “closest” node first the way Dijkstra does; the algorithm just brute-forces every edge repeatedly until distances stop improving.

That relentless simplicity is also what makes it correct with negative weights: it never assumes a distance is final until all V - 1 passes complete, so a cheaper path discovered late still gets picked up on the next relaxation pass.

Detecting negative cycles

A negative cycle is a loop in the graph whose total edge weight is negative — meaning you could walk around it forever, making your total path “cost” lower with every lap, so no shortest path actually exists. Bellman-Ford detects this for free: after the standard V - 1 relaxation passes, run one more pass. If any distance still improves, the graph contains a negative cycle reachable from the source, and no shortest path is well-defined for the nodes affected by it. Dijkstra has no equivalent check — it isn’t designed to reason about cycles at all, since its non-negative assumption rules them out by construction.

This detection step is the reason Bellman-Ford shows up in domains beyond routing: currency arbitrage detection is a direct application, where a negative cycle in a graph of exchange rates corresponds to a real, exploitable arbitrage loop.

Complexity: the price of generality

The tradeoff for that extra guarantee is speed. Dijkstra, implemented with a priority queue (typically a heap), runs in O((V + E) log V) time — it only ever relaxes each edge once it’s confident the relaxation is useful. Bellman-Ford runs in O(V × E) time, because it relaxes every edge on every one of its V - 1 passes, regardless of whether most of those relaxations do nothing. On a dense graph with thousands of nodes, that difference is the gap between a query that returns instantly and one that visibly lags.

Bellman-Ford vs Dijkstra at a glance

Bellman-FordDijkstra
Negative edge weightsSupportedNot supported (incorrect results)
Negative cycle detectionYes, built inNo
Time complexityO(V × E)O((V + E) log V) with a heap
Typical use caseFinancial/arbitrage graphs, distance-vector routingRoad networks, general shortest-path
ImplementationSimple, no priority queue neededNeeds a priority queue for best performance

When to reach for each one

If you know every edge weight in your graph is non-negative — road distances, network hop counts, most physical or logical distance metrics — Dijkstra is the better default, and pairing it with a heuristic gets you A* search when you only need the path to one specific destination rather than to every node.

Reach for Bellman-Ford specifically when negative weights are possible, or when detecting a negative cycle is itself the point of running the algorithm. It also has a practical edge in distributed settings: distance-vector routing protocols historically used Bellman-Ford-style relaxation because it’s naturally suited to nodes that only know about their immediate neighbors, unlike Dijkstra’s need for a global view of “which unvisited node is closest.”

The takeaway

Dijkstra and Bellman-Ford solve the same shortest-path problem with opposite priorities: Dijkstra assumes non-negative weights and rewards that assumption with speed; Bellman-Ford drops the assumption, tolerates negative weights, and can detect negative cycles as a byproduct, at the cost of a slower O(V × E) runtime. Use Dijkstra as the default for ordinary distance graphs, and switch to Bellman-Ford the moment negative weights enter the picture.

The Lycoris Team The Lycoris Team · · 4 min read

The Rope Data Structure: Editing Huge Strings Efficiently

A rope is a binary tree of string chunks that makes inserting, deleting, and slicing huge strings fast, which is why text editors use it over plain arrays.

#Computer Science #Data Structures #Algorithms
The Lycoris Team The Lycoris Team · · 4 min read

Memoization vs. Tabulation in Dynamic Programming

Memoization caches results top-down via recursion; tabulation builds a table bottom-up with loops. Same technique, opposite direction, different tradeoffs.

#Computer Science #Algorithms #Data Structures
The Lycoris Team The Lycoris Team · · 4 min read

Manacher's Algorithm Explained

Manacher's algorithm finds the longest palindromic substring in linear time by reusing symmetry from palindromes already found, avoiding redundant checks.

#Computer Science #Algorithms #Data Structures