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, initialise dist[v] = 0 for 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

ProblemNegative cycle means
Currency arbitrage (take of rates)a profitable trading loop exists
Difference constraints the system is infeasible
Min-cost flow cycle cancellingthe current flow is not yet optimal
Scheduling with relative deadlinescontradictory constraints
Game with repeatable profitable movesunbounded 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