A negative cycle is a directed cycle whose edge weights sum to less than zero. Its presence makes “shortest path” meaningless for any vertex that can reach it and be reached from it — you can loop forever and drive the cost to .
Detection
Bellman-Ford —
Run relaxation rounds. Then run one more. If anything still improves, a negative cycle is reachable from the source.
bool hasNegativeCycle(int n, vector<Edge>& edges, int s) {
vector<long long> dist(n, LLONG_MAX / 4);
dist[s] = 0;
for (int i = 0; i < n - 1; i++)
for (auto& e : edges)
if (dist[e.u] + e.w < dist[e.v]) dist[e.v] = dist[e.u] + e.w;
for (auto& e : edges)
if (dist[e.u] + e.w < dist[e.v]) return true; // still improving
return false;
}Reachability matters
This only finds cycles reachable from
s. To detect a negative cycle anywhere, initialisedist[v] = 0for every (equivalent to a virtual source with 0-weight edges to all vertices), then run the same loop.
Extracting the cycle
Keep par[]. If round relaxes vertex , walk par from exactly times to guarantee landing inside the cycle, then follow par until you return to that vertex.
int y = x;
for (int i = 0; i < n; i++) y = par[y]; // now y is on the cycle
vector<int> cyc;
for (int cur = y; ; cur = par[cur]) {
cyc.push_back(cur);
if (cur == y && cyc.size() > 1) break;
}
reverse(cyc.begin(), cyc.end());Floyd-Warshall —
After the main triple loop, a negative cycle exists iff d[i][i] < 0 for some . This finds cycles anywhere in the graph and identifies which vertices are on one.
for (int i = 0; i < n; i++) if (d[i][i] < 0) /* i is on a negative cycle */;To mark every pair affected: if (d[i][k] < INF && d[k][k] < 0 && d[k][j] < INF) d[i][j] = -INF;
SPFA — worst case
Count enqueues; more than for any vertex means a negative cycle. See SPFA. Faster in practice, but hackable.
Minimum mean cycle
A related and often more useful question: find the cycle minimising the average edge weight. Karp’s algorithm does this in with a clean DP over path lengths.
Binary searching and testing “is there a negative cycle after subtracting from every edge?” is the standard alternative — and generalises to minimum cost-to-time ratio problems.
Where negative cycles are the point
| Problem | Negative cycle means |
|---|---|
| Currency arbitrage (take of rates) | a profitable trading loop exists |
| Difference constraints | the system is infeasible |
| Min-cost flow cycle cancelling | the current flow is not yet optimal |
| Scheduling with relative deadlines | contradictory constraints |
| Game with repeatable profitable moves | unbounded score |
Negative edges are fine; negative cycles are not
Bellman-Ford, Floyd-Warshall, Johnson and DAG DP all handle negative edges correctly as long as no negative cycle exists. Only Dijkstra breaks on negative edges alone — and it does so silently.
See also: Bellman-Ford · Karp’s Minimum Mean Cycle · Shortest Paths