ℹ️ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0.1 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://cp-algorithms.com/graph/bellman_ford.html |
| Last Crawled | 2026-04-04 09:59:23 (2 days ago) |
| First Indexed | 2018-06-06 07:23:13 (7 years ago) |
| HTTP Status Code | 200 |
| Meta Title | Bellman-Ford - finding shortest paths with negative weights - Algorithms for Competitive Programming |
| Meta Description | The goal of this project is to translate the wonderful resource http://e-maxx.ru/algo which provides descriptions of many algorithms and data structures especially popular in field of competitive programming. Moreover we want to improve the collected knowledge by extending the articles and adding new articles to the collection. |
| Meta Canonical | null |
| Boilerpipe Text | Last update:
September 10, 2025
Translated
From: e-maxx.ru
Bellman-Ford Algorithm
¶
Single source shortest path with negative weight edges
Suppose that we are given a weighted directed graph
G
with
n
vertices and
m
edges, and some specified vertex
v
. You want to find the length of shortest paths from vertex
v
to every other vertex.
Unlike the Dijkstra algorithm, this algorithm can also be applied to graphs containing negative weight edges . However, if the graph contains a negative cycle, then, clearly, the shortest path to some vertices may not exist (due to the fact that the weight of the shortest path must be equal to minus infinity); however, this algorithm can be modified to signal the presence of a cycle of negative weight, or even deduce this cycle.
The algorithm bears the name of two American scientists: Richard Bellman and Lester Ford. Ford actually invented this algorithm in 1956 during the study of another mathematical problem, which eventually reduced to a subproblem of finding the shortest paths in the graph, and Ford gave an outline of the algorithm to solve this problem. Bellman in 1958 published an article devoted specifically to the problem of finding the shortest path, and in this article he clearly formulated the algorithm in the form in which it is known to us now.
Description of the algorithm
¶
Let us assume that the graph contains no negative weight cycle. The case of presence of a negative weight cycle will be discussed below in a separate section.
We will create an array of distances
d
[
0
…
n
−
1
]
, which after execution of the algorithm will contain the answer to the problem. In the beginning we fill it as follows:
d
[
v
]
=
0
, and all other elements
d
[
]
equal to infinity
∞
.
The algorithm consists of several phases. Each phase scans through all edges of the graph, and the algorithm tries to produce
relaxation
along each edge
(
a
,
b
)
having weight
c
. Relaxation along the edges is an attempt to improve the value
d
[
b
]
using value
d
[
a
]
+
c
. In fact, it means that we are trying to improve the answer for this vertex using edge
(
a
,
b
)
and current answer for vertex
a
.
It is claimed that
n
−
1
phases of the algorithm are sufficient to correctly calculate the lengths of all shortest paths in the graph (again, we believe that the cycles of negative weight do not exist). For unreachable vertices the distance
d
[
]
will remain equal to infinity
∞
.
Implementation
¶
Unlike many other graph algorithms, for Bellman-Ford algorithm, it is more convenient to represent the graph using a single list of all edges (instead of
n
lists of edges - edges from each vertex). We start the implementation with a structure
e
d
g
e
for representing the edges. The input to the algorithm are numbers
n
,
m
, list
e
of edges and the starting vertex
v
. All the vertices are numbered
0
to
n
−
1
.
The simplest implementation
¶
The constant
I
N
F
denotes the number "infinity" — it should be selected in such a way that it is greater than all possible path lengths.
struct
Edge
{
int
a
,
b
,
cost
;
};
int
n
,
m
,
v
;
vector
<
Edge
>
edges
;
const
int
INF
=
1000000000
;
void
solve
()
{
vector
<
int
>
d
(
n
,
INF
);
d
[
v
]
=
0
;
for
(
int
i
=
0
;
i
<
n
-
1
;
++
i
)
for
(
Edge
e
:
edges
)
if
(
d
[
e
.
a
]
<
INF
)
d
[
e
.
b
]
=
min
(
d
[
e
.
b
],
d
[
e
.
a
]
+
e
.
cost
);
// display d, for example, on the screen
}
The check
if (d[e.a] < INF)
is needed only if the graph contains negative weight edges: no such verification would result in relaxation from the vertices to which paths have not yet found, and incorrect distance, of the type
∞
−
1
,
∞
−
2
etc. would appear.
A better implementation
¶
This algorithm can be somewhat speeded up: often we already get the answer in a few phases and no useful work is done in remaining phases, just a waste visiting all edges. So, let's keep the flag, to tell whether something changed in the current phase or not, and if any phase, nothing changed, the algorithm can be stopped. (This optimization does not improve the asymptotic behavior, i.e., some graphs will still need all
n
−
1
phases, but significantly accelerates the behavior of the algorithm "on an average", i.e., on random graphs.)
With this optimization, it is generally unnecessary to restrict manually the number of phases of the algorithm to
n
−
1
— the algorithm will stop after the desired number of phases.
void
solve
()
{
vector
<
int
>
d
(
n
,
INF
);
d
[
v
]
=
0
;
for
(;;)
{
bool
any
=
false
;
for
(
Edge
e
:
edges
)
if
(
d
[
e
.
a
]
<
INF
)
if
(
d
[
e
.
b
]
>
d
[
e
.
a
]
+
e
.
cost
)
{
d
[
e
.
b
]
=
d
[
e
.
a
]
+
e
.
cost
;
any
=
true
;
}
if
(
!
any
)
break
;
}
// display d, for example, on the screen
}
Retrieving Path
¶
Let us now consider how to modify the algorithm so that it not only finds the length of shortest paths, but also allows to reconstruct the shortest paths.
For that, let's create another array
p
[
0
…
n
−
1
]
, where for each vertex we store its "predecessor", i.e. the penultimate vertex in the shortest path leading to it. In fact, the shortest path to any vertex
a
is a shortest path to some vertex
p
[
a
]
, to which we added
a
at the end of the path.
Note that the algorithm works on the same logic: it assumes that the shortest distance to one vertex is already calculated, and, tries to improve the shortest distance to other vertices from that vertex. Therefore, at the time of improvement we just need to remember
p
[
]
, i.e, the vertex from which this improvement has occurred.
Following is an implementation of the Bellman-Ford with the retrieval of shortest path to a given node
t
:
void
solve
()
{
vector
<
int
>
d
(
n
,
INF
);
d
[
v
]
=
0
;
vector
<
int
>
p
(
n
,
-1
);
for
(;;)
{
bool
any
=
false
;
for
(
Edge
e
:
edges
)
if
(
d
[
e
.
a
]
<
INF
)
if
(
d
[
e
.
b
]
>
d
[
e
.
a
]
+
e
.
cost
)
{
d
[
e
.
b
]
=
d
[
e
.
a
]
+
e
.
cost
;
p
[
e
.
b
]
=
e
.
a
;
any
=
true
;
}
if
(
!
any
)
break
;
}
if
(
d
[
t
]
==
INF
)
cout
<<
"No path from "
<<
v
<<
" to "
<<
t
<<
"."
;
else
{
vector
<
int
>
path
;
for
(
int
cur
=
t
;
cur
!=
-1
;
cur
=
p
[
cur
])
path
.
push_back
(
cur
);
reverse
(
path
.
begin
(),
path
.
end
());
cout
<<
"Path from "
<<
v
<<
" to "
<<
t
<<
": "
;
for
(
int
u
:
path
)
cout
<<
u
<<
' '
;
}
}
Here starting from the vertex
t
, we go through the predecessors till we reach starting vertex with no predecessor, and store all the vertices in the path in the list
p
a
t
h
. This list is a shortest path from
v
to
t
, but in reverse order, so we call
r
e
v
e
r
s
e
(
)
function over
p
a
t
h
and then output the path.
The proof of the algorithm
¶
First, note that for all unreachable vertices
u
the algorithm will work correctly, the label
d
[
u
]
will remain equal to infinity (because the algorithm Bellman-Ford will find some way to all reachable vertices from the start vertex
v
, and relaxation for all other remaining vertices will never happen).
Let us now prove the following assertion: After the execution of
i
t
h
phase, the Bellman-Ford algorithm correctly finds all shortest paths whose number of edges does not exceed
i
.
In other words, for any vertex
a
let us denote the
k
number of edges in the shortest path to it (if there are several such paths, you can take any). According to this statement, the algorithm guarantees that after
k
t
h
phase the shortest path for vertex
a
will be found.
Proof
:
Consider an arbitrary vertex
a
to which there is a path from the starting vertex
v
, and consider a shortest path to it
(
p
0
=
v
,
p
1
,
…
,
p
k
=
a
)
. Before the first phase, the shortest path to the vertex
p
0
=
v
was found correctly. During the first phase, the edge
(
p
0
,
p
1
)
has been checked by the algorithm, and therefore, the distance to the vertex
p
1
was correctly calculated after the first phase. Repeating this statement
k
times, we see that after
k
t
h
phase the distance to the vertex
p
k
=
a
gets calculated correctly, which we wanted to prove.
The last thing to notice is that any shortest path cannot have more than
n
−
1
edges. Therefore, the algorithm sufficiently goes up to the
(
n
−
1
)
t
h
phase. After that, it is guaranteed that no relaxation will improve the distance to some vertex.
The case of a negative cycle
¶
Everywhere above we considered that there is no negative cycle in the graph (precisely, we are interested in a negative cycle that is reachable from the starting vertex
v
, and, for an unreachable cycles nothing in the above algorithm changes). In the presence of a negative cycle(s), there are further complications associated with the fact that distances to all vertices in this cycle, as well as the distances to the vertices reachable from this cycle is not defined — they should be equal to minus infinity
(
−
∞
)
.
It is easy to see that the Bellman-Ford algorithm can endlessly do the relaxation among all vertices of this cycle and the vertices reachable from it. Therefore, if you do not limit the number of phases to
n
−
1
, the algorithm will run indefinitely, constantly improving the distance from these vertices.
Hence we obtain the
criterion for presence of a cycle of negative weights reachable for source vertex
v
: after
(
n
−
1
)
t
h
phase, if we run algorithm for one more phase, and it performs at least one more relaxation, then the graph contains a negative weight cycle that is reachable from
v
; otherwise, such a cycle does not exist.
Moreover, if such a cycle is found, the Bellman-Ford algorithm can be modified so that it retrieves this cycle as a sequence of vertices contained in it. For this, it is sufficient to remember the last vertex
x
for which there was a relaxation in
n
t
h
phase. This vertex will either lie on a negative weight cycle, or is reachable from it. To get the vertices that are guaranteed to lie on a negative cycle, starting from the vertex
x
, pass through to the predecessors
n
times. In this way, we will get to the vertex
y
, which is guaranteed to lie on a negative cycle. We have to go from this vertex, through the predecessors, until we get back to the same vertex
y
(and it will happen, because relaxation in a negative weight cycle occur in a circular manner).
Implementation:
¶
void
solve
()
{
vector
<
int
>
d
(
n
,
INF
);
d
[
v
]
=
0
;
vector
<
int
>
p
(
n
,
-1
);
int
x
;
for
(
int
i
=
0
;
i
<
n
;
++
i
)
{
x
=
-1
;
for
(
Edge
e
:
edges
)
if
(
d
[
e
.
a
]
<
INF
)
if
(
d
[
e
.
b
]
>
d
[
e
.
a
]
+
e
.
cost
)
{
d
[
e
.
b
]
=
max
(
-
INF
,
d
[
e
.
a
]
+
e
.
cost
);
p
[
e
.
b
]
=
e
.
a
;
x
=
e
.
b
;
}
}
if
(
x
==
-1
)
cout
<<
"No negative cycle from "
<<
v
;
else
{
int
y
=
x
;
for
(
int
i
=
0
;
i
<
n
;
++
i
)
y
=
p
[
y
];
vector
<
int
>
path
;
for
(
int
cur
=
y
;;
cur
=
p
[
cur
])
{
path
.
push_back
(
cur
);
if
(
cur
==
y
&&
path
.
size
()
>
1
)
break
;
}
reverse
(
path
.
begin
(),
path
.
end
());
cout
<<
"Negative cycle: "
;
for
(
int
u
:
path
)
cout
<<
u
<<
' '
;
}
}
Due to the presence of a negative cycle, for
n
iterations of the algorithm, the distances may go far in the negative range (to negative numbers of the order of
−
n
m
W
, where
W
is the maximum absolute value of any weight in the graph). Hence in the code, we adopted additional measures against the integer overflow as follows:
d
[
e
.
b
]
=
max
(
-
INF
,
d
[
e
.
a
]
+
e
.
cost
);
The above implementation looks for a negative cycle reachable from some starting vertex
v
; however, the algorithm can be modified to just look for any negative cycle in the graph. For this we need to put all the distance
d
[
i
]
to zero and not infinity — as if we are looking for the shortest path from all vertices simultaneously; the validity of the detection of a negative cycle is not affected.
For more on this topic — see separate article,
Finding a negative cycle in the graph
.
Shortest Path Faster Algorithm (SPFA)
¶
SPFA is a improvement of the Bellman-Ford algorithm which takes advantage of the fact that not all attempts at relaxation will work.
The main idea is to create a queue containing only the vertices that were relaxed but that still could further relax their neighbors.
And whenever you can relax some neighbor, you should put him in the queue. This algorithm can also be used to detect negative cycles as the Bellman-Ford.
The worst case of this algorithm is equal to the
O
(
n
m
)
of the Bellman-Ford, but in practice it works much faster and some
people claim that it works even in
O
(
m
)
on average
. However be careful, because this algorithm is deterministic and it is easy to create counterexamples that make the algorithm run in
O
(
n
m
)
.
There are some care to be taken in the implementation, such as the fact that the algorithm continues forever if there is a negative cycle.
To avoid this, it is possible to create a counter that stores how many times a vertex has been relaxed and stop the algorithm as soon as some vertex got relaxed for the
n
-th time.
Note, also there is no reason to put a vertex in the queue if it is already in.
const
int
INF
=
1000000000
;
vector
<
vector
<
pair
<
int
,
int
>>>
adj
;
bool
spfa
(
int
s
,
vector
<
int
>&
d
)
{
int
n
=
adj
.
size
();
d
.
assign
(
n
,
INF
);
vector
<
int
>
cnt
(
n
,
0
);
vector
<
bool
>
inqueue
(
n
,
false
);
queue
<
int
>
q
;
d
[
s
]
=
0
;
q
.
push
(
s
);
inqueue
[
s
]
=
true
;
while
(
!
q
.
empty
())
{
int
v
=
q
.
front
();
q
.
pop
();
inqueue
[
v
]
=
false
;
for
(
auto
edge
:
adj
[
v
])
{
int
to
=
edge
.
first
;
int
len
=
edge
.
second
;
if
(
d
[
v
]
+
len
<
d
[
to
])
{
d
[
to
]
=
d
[
v
]
+
len
;
if
(
!
inqueue
[
to
])
{
q
.
push
(
to
);
inqueue
[
to
]
=
true
;
cnt
[
to
]
++
;
if
(
cnt
[
to
]
>
n
)
return
false
;
// negative cycle
}
}
}
}
return
true
;
}
A list of tasks that can be solved using the Bellman-Ford algorithm:
E-OLYMP #1453 "Ford-Bellman" [difficulty: low]
UVA #423 "MPI Maelstrom" [difficulty: low]
UVA #534 "Frogger" [difficulty: medium]
UVA #10099 "The Tourist Guide" [difficulty: medium]
UVA #515 "King" [difficulty: medium]
UVA 12519 - The Farnsworth Parabox
See also the problem list in the article
Finding the negative cycle in a graph
.
*
CSES - High Score
*
CSES - Cycle Finding
Contributors:
bimalkant-lauhny
(53.11%)
wangwillian0
(17.95%)
jakobkogler
(16.12%)
likecs
(3.66%)
adamant-pwn
(2.57%)
RodionGork
(2.56%)
aryamanjain-scifin
(0.73%)
aleksmish
(0.37%)
joaomarcosth9
(0.37%)
Aman-Codes
(0.37%)
orendon
(0.37%)
DiegoHDMGZ
(0.37%)
pirateksh
(0.37%)
sachinpatel9135
(0.37%)
prprprpony
(0.37%)
Morass
(0.37%) |
| Markdown | [Skip to content](https://cp-algorithms.com/graph/bellman_ford.html#bellman-ford-algorithm)
[](https://cp-algorithms.com/ "Algorithms for Competitive Programming")
[Algorithms for Competitive Programming](https://cp-algorithms.com/ "Algorithms for Competitive Programming")
[Bellman-Ford - finding shortest paths with negative weights](https://cp-algorithms.com/graph/bellman_ford.html)
Type to start searching
[cp-algorithms/cp-algorithms 10.4k 2k](https://github.com/cp-algorithms/cp-algorithms "Go to repository")
[](https://cp-algorithms.com/ "Algorithms for Competitive Programming") Algorithms for Competitive Programming
[cp-algorithms/cp-algorithms 10.4k 2k](https://github.com/cp-algorithms/cp-algorithms "Go to repository")
- Home
Home
- [Main Page](https://cp-algorithms.com/index.html)
- [Navigation](https://cp-algorithms.com/navigation.html)
- [Tag index](https://cp-algorithms.com/tags.html)
- [How to Contribute](https://cp-algorithms.com/contrib.html)
- [Code of conduct](https://cp-algorithms.com/code_of_conduct.html)
- [Preview](https://cp-algorithms.com/preview.html)
- Algebra
Algebra
- Fundamentals
Fundamentals
- [Binary Exponentiation](https://cp-algorithms.com/algebra/binary-exp.html)
- [Euclidean algorithm for computing the greatest common divisor](https://cp-algorithms.com/algebra/euclid-algorithm.html)
- [Extended Euclidean Algorithm](https://cp-algorithms.com/algebra/extended-euclid-algorithm.html)
- [Linear Diophantine Equations](https://cp-algorithms.com/algebra/linear-diophantine-equation.html)
- [Fibonacci Numbers](https://cp-algorithms.com/algebra/fibonacci-numbers.html)
- Prime numbers
Prime numbers
- [Sieve of Eratosthenes](https://cp-algorithms.com/algebra/sieve-of-eratosthenes.html)
- [Linear Sieve](https://cp-algorithms.com/algebra/prime-sieve-linear.html)
- [Primality tests](https://cp-algorithms.com/algebra/primality_tests.html)
- [Integer factorization](https://cp-algorithms.com/algebra/factorization.html)
- Number-theoretic functions
Number-theoretic functions
- [Euler's totient function](https://cp-algorithms.com/algebra/phi-function.html)
- [Number of divisors / sum of divisors](https://cp-algorithms.com/algebra/divisors.html)
- Modular arithmetic
Modular arithmetic
- [Modular Inverse](https://cp-algorithms.com/algebra/module-inverse.html)
- [Linear Congruence Equation](https://cp-algorithms.com/algebra/linear_congruence_equation.html)
- [Chinese Remainder Theorem](https://cp-algorithms.com/algebra/chinese-remainder-theorem.html)
- [Garner's Algorithm](https://cp-algorithms.com/algebra/garners-algorithm.html)
- [Factorial modulo p](https://cp-algorithms.com/algebra/factorial-modulo.html)
- [Discrete Log](https://cp-algorithms.com/algebra/discrete-log.html)
- [Primitive Root](https://cp-algorithms.com/algebra/primitive-root.html)
- [Discrete Root](https://cp-algorithms.com/algebra/discrete-root.html)
- [Montgomery Multiplication](https://cp-algorithms.com/algebra/montgomery_multiplication.html)
- Number systems
Number systems
- [Balanced Ternary](https://cp-algorithms.com/algebra/balanced-ternary.html)
- [Gray code](https://cp-algorithms.com/algebra/gray-code.html)
- Miscellaneous
Miscellaneous
- [Bit manipulation](https://cp-algorithms.com/algebra/bit-manipulation.html)
- [Enumerating submasks of a bitmask](https://cp-algorithms.com/algebra/all-submasks.html)
- [Arbitrary-Precision Arithmetic](https://cp-algorithms.com/algebra/big-integer.html)
- [Fast Fourier transform](https://cp-algorithms.com/algebra/fft.html)
- [Operations on polynomials and series](https://cp-algorithms.com/algebra/polynomial.html)
- [Continued fractions](https://cp-algorithms.com/algebra/continued-fractions.html)
- [Factoring Exponentiation](https://cp-algorithms.com/algebra/factoring-exp.html)
- Data Structures
Data Structures
- Fundamentals
Fundamentals
- [Minimum Stack / Minimum Queue](https://cp-algorithms.com/data_structures/stack_queue_modification.html)
- [Sparse Table](https://cp-algorithms.com/data_structures/sparse-table.html)
- Trees
Trees
- [Disjoint Set Union](https://cp-algorithms.com/data_structures/disjoint_set_union.html)
- [Fenwick Tree](https://cp-algorithms.com/data_structures/fenwick.html)
- [Sqrt Decomposition](https://cp-algorithms.com/data_structures/sqrt_decomposition.html)
- [Segment Tree](https://cp-algorithms.com/data_structures/segment_tree.html)
- [Treap](https://cp-algorithms.com/data_structures/treap.html)
- [Sqrt Tree](https://cp-algorithms.com/data_structures/sqrt-tree.html)
- [Randomized Heap](https://cp-algorithms.com/data_structures/randomized_heap.html)
- Advanced
Advanced
- [Deleting from a data structure in O(T(n) log n)](https://cp-algorithms.com/data_structures/deleting_in_log_n.html)
- Dynamic Programming
Dynamic Programming
- [Introduction to Dynamic Programming](https://cp-algorithms.com/dynamic_programming/intro-to-dp.html)
- [Knapsack Problem](https://cp-algorithms.com/dynamic_programming/knapsack.html)
- [Longest increasing subsequence](https://cp-algorithms.com/dynamic_programming/longest_increasing_subsequence.html)
- DP optimizations
DP optimizations
- [Divide and Conquer DP](https://cp-algorithms.com/dynamic_programming/divide-and-conquer-dp.html)
- [Knuth's Optimization](https://cp-algorithms.com/dynamic_programming/knuth-optimization.html)
- Tasks
Tasks
- [Dynamic Programming on Broken Profile. Problem "Parquet"](https://cp-algorithms.com/dynamic_programming/profile-dynamics.html)
- [Finding the largest zero submatrix](https://cp-algorithms.com/dynamic_programming/zero_matrix.html)
- String Processing
String Processing
- Fundamentals
Fundamentals
- [String Hashing](https://cp-algorithms.com/string/string-hashing.html)
- [Rabin-Karp for String Matching](https://cp-algorithms.com/string/rabin-karp.html)
- [Prefix function - Knuth-Morris-Pratt](https://cp-algorithms.com/string/prefix-function.html)
- [Z-function](https://cp-algorithms.com/string/z-function.html)
- [Suffix Array](https://cp-algorithms.com/string/suffix-array.html)
- [Aho-Corasick algorithm](https://cp-algorithms.com/string/aho_corasick.html)
- Advanced
Advanced
- [Suffix Tree](https://cp-algorithms.com/string/suffix-tree-ukkonen.html)
- [Suffix Automaton](https://cp-algorithms.com/string/suffix-automaton.html)
- [Lyndon factorization](https://cp-algorithms.com/string/lyndon_factorization.html)
- Tasks
Tasks
- [Expression parsing](https://cp-algorithms.com/string/expression_parsing.html)
- [Manacher's Algorithm - Finding all sub-palindromes in O(N)](https://cp-algorithms.com/string/manacher.html)
- [Finding repetitions](https://cp-algorithms.com/string/main_lorentz.html)
- Linear Algebra
Linear Algebra
- Matrices
Matrices
- [Gauss & System of Linear Equations](https://cp-algorithms.com/linear_algebra/linear-system-gauss.html)
- [Gauss & Determinant](https://cp-algorithms.com/linear_algebra/determinant-gauss.html)
- [Kraut & Determinant](https://cp-algorithms.com/linear_algebra/determinant-kraut.html)
- [Rank of a matrix](https://cp-algorithms.com/linear_algebra/rank-matrix.html)
- Combinatorics
Combinatorics
- Fundamentals
Fundamentals
- [Finding Power of Factorial Divisor](https://cp-algorithms.com/algebra/factorial-divisors.html)
- [Binomial Coefficients](https://cp-algorithms.com/combinatorics/binomial-coefficients.html)
- [Catalan Numbers](https://cp-algorithms.com/combinatorics/catalan-numbers.html)
- Techniques
Techniques
- [The Inclusion-Exclusion Principle](https://cp-algorithms.com/combinatorics/inclusion-exclusion.html)
- [Burnside's lemma / Pólya enumeration theorem](https://cp-algorithms.com/combinatorics/burnside.html)
- [Stars and bars](https://cp-algorithms.com/combinatorics/stars_and_bars.html)
- [Generating all K-combinations](https://cp-algorithms.com/combinatorics/generating_combinations.html)
- Tasks
Tasks
- [Placing Bishops on a Chessboard](https://cp-algorithms.com/combinatorics/bishops-on-chessboard.html)
- [Balanced bracket sequences](https://cp-algorithms.com/combinatorics/bracket_sequences.html)
- [Counting labeled graphs](https://cp-algorithms.com/combinatorics/counting_labeled_graphs.html)
- Numerical Methods
Numerical Methods
- Search
Search
- [Binary Search](https://cp-algorithms.com/num_methods/binary_search.html)
- [Ternary Search](https://cp-algorithms.com/num_methods/ternary_search.html)
- [Newton's method for finding roots](https://cp-algorithms.com/num_methods/roots_newton.html)
- [Simulated Annealing](https://cp-algorithms.com/num_methods/simulated_annealing.html)
- Integration
Integration
- [Integration by Simpson's formula](https://cp-algorithms.com/num_methods/simpson-integration.html)
- Geometry
Geometry
- Elementary operations
Elementary operations
- [Basic Geometry](https://cp-algorithms.com/geometry/basic-geometry.html)
- [Finding the equation of a line for a segment](https://cp-algorithms.com/geometry/segment-to-line.html)
- [Intersection Point of Lines](https://cp-algorithms.com/geometry/lines-intersection.html)
- [Check if two segments intersect](https://cp-algorithms.com/geometry/check-segments-intersection.html)
- [Intersection of Segments](https://cp-algorithms.com/geometry/segments-intersection.html)
- [Circle-Line Intersection](https://cp-algorithms.com/geometry/circle-line-intersection.html)
- [Circle-Circle Intersection](https://cp-algorithms.com/geometry/circle-circle-intersection.html)
- [Common tangents to two circles](https://cp-algorithms.com/geometry/tangents-to-two-circles.html)
- [Length of the union of segments](https://cp-algorithms.com/geometry/length-of-segments-union.html)
- Polygons
Polygons
- [Oriented area of a triangle](https://cp-algorithms.com/geometry/oriented-triangle-area.html)
- [Area of simple polygon](https://cp-algorithms.com/geometry/area-of-simple-polygon.html)
- [Check if points belong to the convex polygon in O(log N)](https://cp-algorithms.com/geometry/point-in-convex-polygon.html)
- [Minkowski sum of convex polygons](https://cp-algorithms.com/geometry/minkowski.html)
- [Pick's Theorem - area of lattice polygons](https://cp-algorithms.com/geometry/picks-theorem.html)
- [Lattice points of non-lattice polygon](https://cp-algorithms.com/geometry/lattice-points.html)
- Convex hull
Convex hull
- [Convex hull construction](https://cp-algorithms.com/geometry/convex-hull.html)
- [Convex hull trick and Li Chao tree](https://cp-algorithms.com/geometry/convex_hull_trick.html)
- Sweep-line
Sweep-line
- [Search for a pair of intersecting segments](https://cp-algorithms.com/geometry/intersecting_segments.html)
- Planar graphs
Planar graphs
- [Finding faces of a planar graph](https://cp-algorithms.com/geometry/planar.html)
- [Point location in O(log N)](https://cp-algorithms.com/geometry/point-location.html)
- Miscellaneous
Miscellaneous
- [Finding the nearest pair of points](https://cp-algorithms.com/geometry/nearest_points.html)
- [Delaunay triangulation and Voronoi diagram](https://cp-algorithms.com/geometry/delaunay.html)
- [Vertical decomposition](https://cp-algorithms.com/geometry/vertical_decomposition.html)
- [Half-plane intersection - S\&I Algorithm in O(N log N)](https://cp-algorithms.com/geometry/halfplane-intersection.html)
- [Manhattan Distance](https://cp-algorithms.com/geometry/manhattan-distance.html)
- [Minimum Enclosing Circle](https://cp-algorithms.com/geometry/enclosing-circle.html)
- Graphs
Graphs
- Graph traversal
Graph traversal
- [Breadth First Search](https://cp-algorithms.com/graph/breadth-first-search.html)
- [Depth First Search](https://cp-algorithms.com/graph/depth-first-search.html)
- Connected components, bridges, articulations points
Connected components, bridges, articulations points
- [Finding Connected Components](https://cp-algorithms.com/graph/search-for-connected-components.html)
- [Finding Bridges in O(N+M)](https://cp-algorithms.com/graph/bridge-searching.html)
- [Finding Bridges Online](https://cp-algorithms.com/graph/bridge-searching-online.html)
- [Finding Articulation Points in O(N+M)](https://cp-algorithms.com/graph/cutpoints.html)
- [Strongly Connected Components and Condensation Graph](https://cp-algorithms.com/graph/strongly-connected-components.html)
- [Strong Orientation](https://cp-algorithms.com/graph/strong-orientation.html)
- Single-source shortest paths
Single-source shortest paths
- [Dijkstra - finding shortest paths from given vertex](https://cp-algorithms.com/graph/dijkstra.html)
- [Dijkstra on sparse graphs](https://cp-algorithms.com/graph/dijkstra_sparse.html)
- Bellman-Ford - finding shortest paths with negative weights
[Bellman-Ford - finding shortest paths with negative weights](https://cp-algorithms.com/graph/bellman_ford.html)
Table of contents
- [Description of the algorithm](https://cp-algorithms.com/graph/bellman_ford.html#description-of-the-algorithm)
- [Implementation](https://cp-algorithms.com/graph/bellman_ford.html#implementation)
- [The simplest implementation](https://cp-algorithms.com/graph/bellman_ford.html#the-simplest-implementation)
- [A better implementation](https://cp-algorithms.com/graph/bellman_ford.html#a-better-implementation)
- [Retrieving Path](https://cp-algorithms.com/graph/bellman_ford.html#retrieving-path)
- [The proof of the algorithm](https://cp-algorithms.com/graph/bellman_ford.html#the-proof-of-the-algorithm)
- [The case of a negative cycle](https://cp-algorithms.com/graph/bellman_ford.html#the-case-of-a-negative-cycle)
- [Implementation:](https://cp-algorithms.com/graph/bellman_ford.html#implementation_1)
- [Shortest Path Faster Algorithm (SPFA)](https://cp-algorithms.com/graph/bellman_ford.html#shortest-path-faster-algorithm-spfa)
- [Related problems in online judges](https://cp-algorithms.com/graph/bellman_ford.html#related-problems-in-online-judges)
- [0-1 BFS](https://cp-algorithms.com/graph/01_bfs.html)
- [D´Esopo-Pape algorithm](https://cp-algorithms.com/graph/desopo_pape.html)
- All-pairs shortest paths
All-pairs shortest paths
- [Floyd-Warshall - finding all shortest paths](https://cp-algorithms.com/graph/all-pair-shortest-path-floyd-warshall.html)
- [Number of paths of fixed length / Shortest paths of fixed length](https://cp-algorithms.com/graph/fixed_length_paths.html)
- Spanning trees
Spanning trees
- [Minimum Spanning Tree - Prim's Algorithm](https://cp-algorithms.com/graph/mst_prim.html)
- [Minimum Spanning Tree - Kruskal](https://cp-algorithms.com/graph/mst_kruskal.html)
- [Minimum Spanning Tree - Kruskal with Disjoint Set Union](https://cp-algorithms.com/graph/mst_kruskal_with_dsu.html)
- [Second best Minimum Spanning Tree - Using Kruskal and Lowest Common Ancestor](https://cp-algorithms.com/graph/second_best_mst.html)
- [Kirchhoff Theorem](https://cp-algorithms.com/graph/kirchhoff-theorem.html)
- [Prüfer code](https://cp-algorithms.com/graph/pruefer_code.html)
- Cycles
Cycles
- [Checking a graph for acyclicity and finding a cycle in O(M)](https://cp-algorithms.com/graph/finding-cycle.html)
- [Finding a Negative Cycle in the Graph](https://cp-algorithms.com/graph/finding-negative-cycle-in-graph.html)
- [Eulerian Path](https://cp-algorithms.com/graph/euler_path.html)
- Lowest common ancestor
Lowest common ancestor
- [Lowest Common Ancestor](https://cp-algorithms.com/graph/lca.html)
- [Lowest Common Ancestor - Binary Lifting](https://cp-algorithms.com/graph/lca_binary_lifting.html)
- [Lowest Common Ancestor - Farach-Colton and Bender algorithm](https://cp-algorithms.com/graph/lca_farachcoltonbender.html)
- [Solve RMQ by finding LCA](https://cp-algorithms.com/graph/rmq_linear.html)
- [Lowest Common Ancestor - Tarjan's off-line algorithm](https://cp-algorithms.com/graph/lca_tarjan.html)
- Flows and related problems
Flows and related problems
- [Maximum flow - Ford-Fulkerson and Edmonds-Karp](https://cp-algorithms.com/graph/edmonds_karp.html)
- [Maximum flow - Push-relabel algorithm](https://cp-algorithms.com/graph/push-relabel.html)
- [Maximum flow - Push-relabel algorithm improved](https://cp-algorithms.com/graph/push-relabel-faster.html)
- [Maximum flow - Dinic's algorithm](https://cp-algorithms.com/graph/dinic.html)
- [Maximum flow - MPM algorithm](https://cp-algorithms.com/graph/mpm.html)
- [Flows with demands](https://cp-algorithms.com/graph/flow_with_demands.html)
- [Minimum-cost flow](https://cp-algorithms.com/graph/min_cost_flow.html)
- [Assignment problem](https://cp-algorithms.com/graph/Assignment-problem-min-flow.html)
- Matchings and related problems
Matchings and related problems
- [Bipartite Graph Check](https://cp-algorithms.com/graph/bipartite-check.html)
- [Kuhn's Algorithm - Maximum Bipartite Matching](https://cp-algorithms.com/graph/kuhn_maximum_bipartite_matching.html)
- [Hungarian Algorithm](https://cp-algorithms.com/graph/hungarian-algorithm.html)
- Miscellaneous
Miscellaneous
- [Topological Sorting](https://cp-algorithms.com/graph/topological-sort.html)
- [Edge connectivity / Vertex connectivity](https://cp-algorithms.com/graph/edge_vertex_connectivity.html)
- [Tree painting](https://cp-algorithms.com/graph/tree_painting.html)
- [2-SAT](https://cp-algorithms.com/graph/2SAT.html)
- [Heavy-light decomposition](https://cp-algorithms.com/graph/hld.html)
- [Centroid decomposition](https://cp-algorithms.com/graph/centroid_decomposition.html)
- Miscellaneous
Miscellaneous
- Sequences
Sequences
- [RMQ task (Range Minimum Query - the smallest element in an interval)](https://cp-algorithms.com/sequences/rmq.html)
- [Search the subsegment with the maximum/minimum sum](https://cp-algorithms.com/others/maximum_average_segment.html)
- [K-th order statistic in O(N)](https://cp-algorithms.com/sequences/k-th.html)
- [MEX task (Minimal Excluded element in an array)](https://cp-algorithms.com/sequences/mex.html)
- Game Theory
Game Theory
- [Games on arbitrary graphs](https://cp-algorithms.com/game_theory/games_on_graphs.html)
- [Sprague-Grundy theorem. Nim](https://cp-algorithms.com/game_theory/sprague-grundy-nim.html)
- Schedules
Schedules
- [Scheduling jobs on one machine](https://cp-algorithms.com/schedules/schedule_one_machine.html)
- [Scheduling jobs on two machines](https://cp-algorithms.com/schedules/schedule_two_machines.html)
- [Optimal schedule of jobs given their deadlines and durations](https://cp-algorithms.com/schedules/schedule-with-completion-duration.html)
- Miscellaneous
Miscellaneous
- [Tortoise and Hare Algorithm (Linked List cycle detection)](https://cp-algorithms.com/others/tortoise_and_hare.html)
- [Josephus problem](https://cp-algorithms.com/others/josephus_problem.html)
- [15 Puzzle Game: Existence Of The Solution](https://cp-algorithms.com/others/15-puzzle.html)
- [The Stern-Brocot Tree and Farey Sequences](https://cp-algorithms.com/others/stern_brocot_tree_farey_sequences.html)
**Please consider [supporting us](https://github.com/sponsors/cp-algorithms)** — ad-free, volunteer-run.
×
# Bellman-Ford Algorithm[¶](https://cp-algorithms.com/graph/bellman_ford.html#bellman-ford-algorithm "Permanent link")
**Single source shortest path with negative weight edges**
Suppose that we are given a weighted directed graph G \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>G\</mi\>\</math\> \$G\$ with n \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>n\</mi\>\</math\> \$n\$ vertices and m \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>m\</mi\>\</math\> \$m\$ edges, and some specified vertex v \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>v\</mi\>\</math\> \$v\$. You want to find the length of shortest paths from vertex v \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>v\</mi\>\</math\> \$v\$ to every other vertex.
Unlike the Dijkstra algorithm, this algorithm can also be applied to graphs containing negative weight edges . However, if the graph contains a negative cycle, then, clearly, the shortest path to some vertices may not exist (due to the fact that the weight of the shortest path must be equal to minus infinity); however, this algorithm can be modified to signal the presence of a cycle of negative weight, or even deduce this cycle.
The algorithm bears the name of two American scientists: Richard Bellman and Lester Ford. Ford actually invented this algorithm in 1956 during the study of another mathematical problem, which eventually reduced to a subproblem of finding the shortest paths in the graph, and Ford gave an outline of the algorithm to solve this problem. Bellman in 1958 published an article devoted specifically to the problem of finding the shortest path, and in this article he clearly formulated the algorithm in the form in which it is known to us now.
## Description of the algorithm[¶](https://cp-algorithms.com/graph/bellman_ford.html#description-of-the-algorithm "Permanent link")
Let us assume that the graph contains no negative weight cycle. The case of presence of a negative weight cycle will be discussed below in a separate section.
We will create an array of distances d \[ 0 … n − 1 \] \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>d\</mi\>\<mo stretchy="false"\>\[\</mo\>\<mn\>0\</mn\>\<mo\>…\</mo\>\<mi\>n\</mi\>\<mo\>−\</mo\>\<mn\>1\</mn\>\<mo stretchy="false"\>\]\</mo\>\</math\> \$d\[0 \\ldots n-1\]\$, which after execution of the algorithm will contain the answer to the problem. In the beginning we fill it as follows: d \[ v \] \= 0 \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>d\</mi\>\<mo stretchy="false"\>\[\</mo\>\<mi\>v\</mi\>\<mo stretchy="false"\>\]\</mo\>\<mo\>=\</mo\>\<mn\>0\</mn\>\</math\> \$d\[v\] = 0\$, and all other elements d \[ \] \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>d\</mi\>\<mo stretchy="false"\>\[\</mo\>\<mo stretchy="false"\>\]\</mo\>\</math\> \$d\[ \]\$ equal to infinity ∞ \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi mathvariant="normal"\>∞\</mi\>\</math\> \$\\infty\$.
The algorithm consists of several phases. Each phase scans through all edges of the graph, and the algorithm tries to produce **relaxation** along each edge ( a , b ) \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mo stretchy="false"\>(\</mo\>\<mi\>a\</mi\>\<mo\>,\</mo\>\<mi\>b\</mi\>\<mo stretchy="false"\>)\</mo\>\</math\> \$(a,b)\$ having weight c \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>c\</mi\>\</math\> \$c\$. Relaxation along the edges is an attempt to improve the value d \[ b \] \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>d\</mi\>\<mo stretchy="false"\>\[\</mo\>\<mi\>b\</mi\>\<mo stretchy="false"\>\]\</mo\>\</math\> \$d\[b\]\$ using value d \[ a \] \+ c \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>d\</mi\>\<mo stretchy="false"\>\[\</mo\>\<mi\>a\</mi\>\<mo stretchy="false"\>\]\</mo\>\<mo\>+\</mo\>\<mi\>c\</mi\>\</math\> \$d\[a\] + c\$. In fact, it means that we are trying to improve the answer for this vertex using edge ( a , b ) \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mo stretchy="false"\>(\</mo\>\<mi\>a\</mi\>\<mo\>,\</mo\>\<mi\>b\</mi\>\<mo stretchy="false"\>)\</mo\>\</math\> \$(a,b)\$ and current answer for vertex a \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>a\</mi\>\</math\> \$a\$.
It is claimed that n − 1 \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>n\</mi\>\<mo\>−\</mo\>\<mn\>1\</mn\>\</math\> \$n-1\$ phases of the algorithm are sufficient to correctly calculate the lengths of all shortest paths in the graph (again, we believe that the cycles of negative weight do not exist). For unreachable vertices the distance d \[ \] \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>d\</mi\>\<mo stretchy="false"\>\[\</mo\>\<mo stretchy="false"\>\]\</mo\>\</math\> \$d\[ \]\$ will remain equal to infinity ∞ \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi mathvariant="normal"\>∞\</mi\>\</math\> \$\\infty\$.
## Implementation[¶](https://cp-algorithms.com/graph/bellman_ford.html#implementation "Permanent link")
Unlike many other graph algorithms, for Bellman-Ford algorithm, it is more convenient to represent the graph using a single list of all edges (instead of n \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>n\</mi\>\</math\> \$n\$ lists of edges - edges from each vertex). We start the implementation with a structure e d g e \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi mathvariant="normal"\>e\</mi\>\<mi mathvariant="normal"\>d\</mi\>\<mi mathvariant="normal"\>g\</mi\>\<mi mathvariant="normal"\>e\</mi\>\</math\> \$\\rm edge\$ for representing the edges. The input to the algorithm are numbers n \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>n\</mi\>\</math\> \$n\$, m \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>m\</mi\>\</math\> \$m\$, list e \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>e\</mi\>\</math\> \$e\$ of edges and the starting vertex v \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>v\</mi\>\</math\> \$v\$. All the vertices are numbered 0 \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mn\>0\</mn\>\</math\> \$0\$ to n − 1 \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>n\</mi\>\<mo\>−\</mo\>\<mn\>1\</mn\>\</math\> \$n - 1\$.
### The simplest implementation[¶](https://cp-algorithms.com/graph/bellman_ford.html#the-simplest-implementation "Permanent link")
The constant I N F \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi mathvariant="normal"\>I\</mi\>\<mi mathvariant="normal"\>N\</mi\>\<mi mathvariant="normal"\>F\</mi\>\</math\> \$\\rm INF\$ denotes the number "infinity" — it should be selected in such a way that it is greater than all possible path lengths.
```
```
The check `if (d[e.a] < INF)` is needed only if the graph contains negative weight edges: no such verification would result in relaxation from the vertices to which paths have not yet found, and incorrect distance, of the type ∞ − 1 \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi mathvariant="normal"\>∞\</mi\>\<mo\>−\</mo\>\<mn\>1\</mn\>\</math\> \$\\infty - 1\$, ∞ − 2 \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi mathvariant="normal"\>∞\</mi\>\<mo\>−\</mo\>\<mn\>2\</mn\>\</math\> \$\\infty - 2\$ etc. would appear.
### A better implementation[¶](https://cp-algorithms.com/graph/bellman_ford.html#a-better-implementation "Permanent link")
This algorithm can be somewhat speeded up: often we already get the answer in a few phases and no useful work is done in remaining phases, just a waste visiting all edges. So, let's keep the flag, to tell whether something changed in the current phase or not, and if any phase, nothing changed, the algorithm can be stopped. (This optimization does not improve the asymptotic behavior, i.e., some graphs will still need all n − 1 \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>n\</mi\>\<mo\>−\</mo\>\<mn\>1\</mn\>\</math\> \$n-1\$ phases, but significantly accelerates the behavior of the algorithm "on an average", i.e., on random graphs.)
With this optimization, it is generally unnecessary to restrict manually the number of phases of the algorithm to n − 1 \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>n\</mi\>\<mo\>−\</mo\>\<mn\>1\</mn\>\</math\> \$n-1\$ — the algorithm will stop after the desired number of phases.
```
```
### Retrieving Path[¶](https://cp-algorithms.com/graph/bellman_ford.html#retrieving-path "Permanent link")
Let us now consider how to modify the algorithm so that it not only finds the length of shortest paths, but also allows to reconstruct the shortest paths.
For that, let's create another array p \[ 0 … n − 1 \] \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>p\</mi\>\<mo stretchy="false"\>\[\</mo\>\<mn\>0\</mn\>\<mo\>…\</mo\>\<mi\>n\</mi\>\<mo\>−\</mo\>\<mn\>1\</mn\>\<mo stretchy="false"\>\]\</mo\>\</math\> \$p\[0 \\ldots n-1\]\$, where for each vertex we store its "predecessor", i.e. the penultimate vertex in the shortest path leading to it. In fact, the shortest path to any vertex a \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>a\</mi\>\</math\> \$a\$ is a shortest path to some vertex p \[ a \] \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>p\</mi\>\<mo stretchy="false"\>\[\</mo\>\<mi\>a\</mi\>\<mo stretchy="false"\>\]\</mo\>\</math\> \$p\[a\]\$, to which we added a \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>a\</mi\>\</math\> \$a\$ at the end of the path.
Note that the algorithm works on the same logic: it assumes that the shortest distance to one vertex is already calculated, and, tries to improve the shortest distance to other vertices from that vertex. Therefore, at the time of improvement we just need to remember p \[ \] \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>p\</mi\>\<mo stretchy="false"\>\[\</mo\>\<mo stretchy="false"\>\]\</mo\>\</math\> \$p\[ \]\$, i.e, the vertex from which this improvement has occurred.
Following is an implementation of the Bellman-Ford with the retrieval of shortest path to a given node t \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>t\</mi\>\</math\> \$t\$:
```
```
Here starting from the vertex t \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>t\</mi\>\</math\> \$t\$, we go through the predecessors till we reach starting vertex with no predecessor, and store all the vertices in the path in the list p a t h \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi mathvariant="normal"\>p\</mi\>\<mi mathvariant="normal"\>a\</mi\>\<mi mathvariant="normal"\>t\</mi\>\<mi mathvariant="normal"\>h\</mi\>\</math\> \$\\rm path\$. This list is a shortest path from v \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>v\</mi\>\</math\> \$v\$ to t \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>t\</mi\>\</math\> \$t\$, but in reverse order, so we call r e v e r s e ( ) \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi mathvariant="normal"\>r\</mi\>\<mi mathvariant="normal"\>e\</mi\>\<mi mathvariant="normal"\>v\</mi\>\<mi mathvariant="normal"\>e\</mi\>\<mi mathvariant="normal"\>r\</mi\>\<mi mathvariant="normal"\>s\</mi\>\<mi mathvariant="normal"\>e\</mi\>\<mo stretchy="false"\>(\</mo\>\<mo stretchy="false"\>)\</mo\>\</math\> \$\\rm reverse()\$ function over p a t h \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi mathvariant="normal"\>p\</mi\>\<mi mathvariant="normal"\>a\</mi\>\<mi mathvariant="normal"\>t\</mi\>\<mi mathvariant="normal"\>h\</mi\>\</math\> \$\\rm path\$ and then output the path.
## The proof of the algorithm[¶](https://cp-algorithms.com/graph/bellman_ford.html#the-proof-of-the-algorithm "Permanent link")
First, note that for all unreachable vertices u \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>u\</mi\>\</math\> \$u\$ the algorithm will work correctly, the label d \[ u \] \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>d\</mi\>\<mo stretchy="false"\>\[\</mo\>\<mi\>u\</mi\>\<mo stretchy="false"\>\]\</mo\>\</math\> \$d\[u\]\$ will remain equal to infinity (because the algorithm Bellman-Ford will find some way to all reachable vertices from the start vertex v \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>v\</mi\>\</math\> \$v\$, and relaxation for all other remaining vertices will never happen).
Let us now prove the following assertion: After the execution of i t h \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<msub\>\<mi\>i\</mi\>\<mrow data-mjx-texclass="ORD"\>\<mi\>t\</mi\>\<mi\>h\</mi\>\</mrow\>\</msub\>\</math\> \$i\_{th}\$ phase, the Bellman-Ford algorithm correctly finds all shortest paths whose number of edges does not exceed i \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>i\</mi\>\</math\> \$i\$.
In other words, for any vertex a \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>a\</mi\>\</math\> \$a\$ let us denote the k \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>k\</mi\>\</math\> \$k\$ number of edges in the shortest path to it (if there are several such paths, you can take any). According to this statement, the algorithm guarantees that after k t h \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<msub\>\<mi\>k\</mi\>\<mrow data-mjx-texclass="ORD"\>\<mi\>t\</mi\>\<mi\>h\</mi\>\</mrow\>\</msub\>\</math\> \$k\_{th}\$ phase the shortest path for vertex a \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>a\</mi\>\</math\> \$a\$ will be found.
**Proof**: Consider an arbitrary vertex a \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>a\</mi\>\</math\> \$a\$ to which there is a path from the starting vertex v \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>v\</mi\>\</math\> \$v\$, and consider a shortest path to it ( p 0 \= v , p 1 , … , p k \= a ) \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mo stretchy="false"\>(\</mo\>\<msub\>\<mi\>p\</mi\>\<mn\>0\</mn\>\</msub\>\<mo\>=\</mo\>\<mi\>v\</mi\>\<mo\>,\</mo\>\<msub\>\<mi\>p\</mi\>\<mn\>1\</mn\>\</msub\>\<mo\>,\</mo\>\<mo\>…\</mo\>\<mo\>,\</mo\>\<msub\>\<mi\>p\</mi\>\<mi\>k\</mi\>\</msub\>\<mo\>=\</mo\>\<mi\>a\</mi\>\<mo stretchy="false"\>)\</mo\>\</math\> \$(p\_0=v, p\_1, \\ldots, p\_k=a)\$. Before the first phase, the shortest path to the vertex p 0 \= v \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<msub\>\<mi\>p\</mi\>\<mn\>0\</mn\>\</msub\>\<mo\>=\</mo\>\<mi\>v\</mi\>\</math\> \$p\_0 = v\$ was found correctly. During the first phase, the edge ( p 0 , p 1 ) \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mo stretchy="false"\>(\</mo\>\<msub\>\<mi\>p\</mi\>\<mn\>0\</mn\>\</msub\>\<mo\>,\</mo\>\<msub\>\<mi\>p\</mi\>\<mn\>1\</mn\>\</msub\>\<mo stretchy="false"\>)\</mo\>\</math\> \$(p\_0,p\_1)\$ has been checked by the algorithm, and therefore, the distance to the vertex p 1 \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<msub\>\<mi\>p\</mi\>\<mn\>1\</mn\>\</msub\>\</math\> \$p\_1\$ was correctly calculated after the first phase. Repeating this statement k \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>k\</mi\>\</math\> \$k\$ times, we see that after k t h \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<msub\>\<mi\>k\</mi\>\<mrow data-mjx-texclass="ORD"\>\<mi\>t\</mi\>\<mi\>h\</mi\>\</mrow\>\</msub\>\</math\> \$k\_{th}\$ phase the distance to the vertex p k \= a \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<msub\>\<mi\>p\</mi\>\<mi\>k\</mi\>\</msub\>\<mo\>=\</mo\>\<mi\>a\</mi\>\</math\> \$p\_k = a\$ gets calculated correctly, which we wanted to prove.
The last thing to notice is that any shortest path cannot have more than n − 1 \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>n\</mi\>\<mo\>−\</mo\>\<mn\>1\</mn\>\</math\> \$n - 1\$ edges. Therefore, the algorithm sufficiently goes up to the ( n − 1 ) t h \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mo stretchy="false"\>(\</mo\>\<mi\>n\</mi\>\<mo\>−\</mo\>\<mn\>1\</mn\>\<msub\>\<mo stretchy="false"\>)\</mo\>\<mrow data-mjx-texclass="ORD"\>\<mi\>t\</mi\>\<mi\>h\</mi\>\</mrow\>\</msub\>\</math\> \$(n-1)\_{th}\$ phase. After that, it is guaranteed that no relaxation will improve the distance to some vertex.
## The case of a negative cycle[¶](https://cp-algorithms.com/graph/bellman_ford.html#the-case-of-a-negative-cycle "Permanent link")
Everywhere above we considered that there is no negative cycle in the graph (precisely, we are interested in a negative cycle that is reachable from the starting vertex v \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>v\</mi\>\</math\> \$v\$, and, for an unreachable cycles nothing in the above algorithm changes). In the presence of a negative cycle(s), there are further complications associated with the fact that distances to all vertices in this cycle, as well as the distances to the vertices reachable from this cycle is not defined — they should be equal to minus infinity ( − ∞ ) \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mo stretchy="false"\>(\</mo\>\<mo\>−\</mo\>\<mi mathvariant="normal"\>∞\</mi\>\<mo stretchy="false"\>)\</mo\>\</math\> \$(- \\infty)\$.
It is easy to see that the Bellman-Ford algorithm can endlessly do the relaxation among all vertices of this cycle and the vertices reachable from it. Therefore, if you do not limit the number of phases to n − 1 \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>n\</mi\>\<mo\>−\</mo\>\<mn\>1\</mn\>\</math\> \$n - 1\$, the algorithm will run indefinitely, constantly improving the distance from these vertices.
Hence we obtain the **criterion for presence of a cycle of negative weights reachable for source vertex v \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>v\</mi\>\</math\> \$v\$**: after ( n − 1 ) t h \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mo stretchy="false"\>(\</mo\>\<mi\>n\</mi\>\<mo\>−\</mo\>\<mn\>1\</mn\>\<msub\>\<mo stretchy="false"\>)\</mo\>\<mrow data-mjx-texclass="ORD"\>\<mi\>t\</mi\>\<mi\>h\</mi\>\</mrow\>\</msub\>\</math\> \$(n-1)\_{th}\$ phase, if we run algorithm for one more phase, and it performs at least one more relaxation, then the graph contains a negative weight cycle that is reachable from v \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>v\</mi\>\</math\> \$v\$; otherwise, such a cycle does not exist.
Moreover, if such a cycle is found, the Bellman-Ford algorithm can be modified so that it retrieves this cycle as a sequence of vertices contained in it. For this, it is sufficient to remember the last vertex x \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>x\</mi\>\</math\> \$x\$ for which there was a relaxation in n t h \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<msub\>\<mi\>n\</mi\>\<mrow data-mjx-texclass="ORD"\>\<mi\>t\</mi\>\<mi\>h\</mi\>\</mrow\>\</msub\>\</math\> \$n\_{th}\$ phase. This vertex will either lie on a negative weight cycle, or is reachable from it. To get the vertices that are guaranteed to lie on a negative cycle, starting from the vertex x \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>x\</mi\>\</math\> \$x\$, pass through to the predecessors n \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>n\</mi\>\</math\> \$n\$ times. In this way, we will get to the vertex y \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>y\</mi\>\</math\> \$y\$, which is guaranteed to lie on a negative cycle. We have to go from this vertex, through the predecessors, until we get back to the same vertex y \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>y\</mi\>\</math\> \$y\$ (and it will happen, because relaxation in a negative weight cycle occur in a circular manner).
### Implementation:[¶](https://cp-algorithms.com/graph/bellman_ford.html#implementation_1 "Permanent link")
```
```
Due to the presence of a negative cycle, for n \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>n\</mi\>\</math\> \$n\$ iterations of the algorithm, the distances may go far in the negative range (to negative numbers of the order of − n m W \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mo\>−\</mo\>\<mi\>n\</mi\>\<mi\>m\</mi\>\<mi\>W\</mi\>\</math\> \$-n m W\$, where W \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>W\</mi\>\</math\> \$W\$ is the maximum absolute value of any weight in the graph). Hence in the code, we adopted additional measures against the integer overflow as follows:
```
d[e.b] = max(-INF, d[e.a] + e.cost);
```
The above implementation looks for a negative cycle reachable from some starting vertex v \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>v\</mi\>\</math\> \$v\$; however, the algorithm can be modified to just look for any negative cycle in the graph. For this we need to put all the distance d \[ i \] \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>d\</mi\>\<mo stretchy="false"\>\[\</mo\>\<mi\>i\</mi\>\<mo stretchy="false"\>\]\</mo\>\</math\> \$d\[i\]\$ to zero and not infinity — as if we are looking for the shortest path from all vertices simultaneously; the validity of the detection of a negative cycle is not affected.
For more on this topic — see separate article, [Finding a negative cycle in the graph](https://cp-algorithms.com/graph/finding-negative-cycle-in-graph.html).
## Shortest Path Faster Algorithm (SPFA)[¶](https://cp-algorithms.com/graph/bellman_ford.html#shortest-path-faster-algorithm-spfa "Permanent link")
SPFA is a improvement of the Bellman-Ford algorithm which takes advantage of the fact that not all attempts at relaxation will work. The main idea is to create a queue containing only the vertices that were relaxed but that still could further relax their neighbors. And whenever you can relax some neighbor, you should put him in the queue. This algorithm can also be used to detect negative cycles as the Bellman-Ford.
The worst case of this algorithm is equal to the O ( n m ) \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>O\</mi\>\<mo stretchy="false"\>(\</mo\>\<mi\>n\</mi\>\<mi\>m\</mi\>\<mo stretchy="false"\>)\</mo\>\</math\> \$O(n m)\$ of the Bellman-Ford, but in practice it works much faster and some [people claim that it works even in O ( m ) \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>O\</mi\>\<mo stretchy="false"\>(\</mo\>\<mi\>m\</mi\>\<mo stretchy="false"\>)\</mo\>\</math\> \$O(m)\$ on average](https://en.wikipedia.org/wiki/Shortest_Path_Faster_Algorithm#Average-case_performance). However be careful, because this algorithm is deterministic and it is easy to create counterexamples that make the algorithm run in O ( n m ) \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>O\</mi\>\<mo stretchy="false"\>(\</mo\>\<mi\>n\</mi\>\<mi\>m\</mi\>\<mo stretchy="false"\>)\</mo\>\</math\> \$O(n m)\$.
There are some care to be taken in the implementation, such as the fact that the algorithm continues forever if there is a negative cycle. To avoid this, it is possible to create a counter that stores how many times a vertex has been relaxed and stop the algorithm as soon as some vertex got relaxed for the n \<math xmlns="http://www.w3.org/1998/Math/MathML"\>\<mi\>n\</mi\>\</math\> \$n\$\-th time. Note, also there is no reason to put a vertex in the queue if it is already in.
```
```
## Related problems in online judges[¶](https://cp-algorithms.com/graph/bellman_ford.html#related-problems-in-online-judges "Permanent link")
A list of tasks that can be solved using the Bellman-Ford algorithm:
- [E-OLYMP \#1453 "Ford-Bellman" \[difficulty: low\]](https://www.e-olymp.com/en/problems/1453)
- [UVA \#423 "MPI Maelstrom" \[difficulty: low\]](http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=364)
- [UVA \#534 "Frogger" \[difficulty: medium\]](http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=7&page=show_problem&problem=475)
- [UVA \#10099 "The Tourist Guide" \[difficulty: medium\]](http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=12&page=show_problem&problem=1040)
- [UVA \#515 "King" \[difficulty: medium\]](http://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=456)
- [UVA 12519 - The Farnsworth Parabox](https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3964)
See also the problem list in the article [Finding the negative cycle in a graph](https://cp-algorithms.com/graph/finding-negative-cycle-in-graph.html). \* [CSES - High Score](https://cses.fi/problemset/task/1673) \* [CSES - Cycle Finding](https://cses.fi/problemset/task/1197)
- - [bimalkant-lauhny](https://github.com/bimalkant-lauhny "bimalkant-lauhny") (53.11%)
- [wangwillian0](https://github.com/wangwillian0 "wangwillian0") (17.95%)
- [jakobkogler](https://github.com/jakobkogler "jakobkogler") (16.12%)
- [likecs](https://github.com/likecs "likecs") (3.66%)
- [adamant-pwn](https://github.com/adamant-pwn "adamant-pwn") (2.57%)
- [RodionGork](https://github.com/RodionGork "RodionGork") (2.56%)
- [aryamanjain-scifin](https://github.com/aryamanjain-scifin "aryamanjain-scifin") (0.73%)
- [aleksmish](https://github.com/aleksmish "aleksmish") (0.37%)
- [joaomarcosth9](https://github.com/joaomarcosth9 "joaomarcosth9") (0.37%)
- [Aman-Codes](https://github.com/Aman-Codes "Aman-Codes") (0.37%)
- [orendon](https://github.com/orendon "orendon") (0.37%)
- [DiegoHDMGZ](https://github.com/DiegoHDMGZ "DiegoHDMGZ") (0.37%)
- [pirateksh](https://github.com/pirateksh "pirateksh") (0.37%)
- [sachinpatel9135](https://github.com/sachinpatel9135 "sachinpatel9135") (0.37%)
- [prprprpony](https://github.com/prprprpony "prprprpony") (0.37%)
- [Morass](https://github.com/Morass "Morass") (0.37%)
Text is available under the [Creative Commons Attribution Share Alike 4.0 International](https://github.com/cp-algorithms/cp-algorithms/blob/main/LICENSE) License
Copyright © 2014 - 2025 by [cp-algorithms contributors](https://github.com/cp-algorithms/cp-algorithms/graphs/contributors)
Made with [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/) |
| Readable Markdown | ## Bellman-Ford Algorithm[¶](https://cp-algorithms.com/graph/bellman_ford.html#bellman-ford-algorithm "Permanent link")
**Single source shortest path with negative weight edges**
Suppose that we are given a weighted directed graph G with n vertices and m edges, and some specified vertex v. You want to find the length of shortest paths from vertex v to every other vertex.
Unlike the Dijkstra algorithm, this algorithm can also be applied to graphs containing negative weight edges . However, if the graph contains a negative cycle, then, clearly, the shortest path to some vertices may not exist (due to the fact that the weight of the shortest path must be equal to minus infinity); however, this algorithm can be modified to signal the presence of a cycle of negative weight, or even deduce this cycle.
The algorithm bears the name of two American scientists: Richard Bellman and Lester Ford. Ford actually invented this algorithm in 1956 during the study of another mathematical problem, which eventually reduced to a subproblem of finding the shortest paths in the graph, and Ford gave an outline of the algorithm to solve this problem. Bellman in 1958 published an article devoted specifically to the problem of finding the shortest path, and in this article he clearly formulated the algorithm in the form in which it is known to us now.
## Description of the algorithm[¶](https://cp-algorithms.com/graph/bellman_ford.html#description-of-the-algorithm "Permanent link")
Let us assume that the graph contains no negative weight cycle. The case of presence of a negative weight cycle will be discussed below in a separate section.
We will create an array of distances d \[ 0 … n − 1 \], which after execution of the algorithm will contain the answer to the problem. In the beginning we fill it as follows: d \[ v \] \= 0, and all other elements d \[ \] equal to infinity ∞.
The algorithm consists of several phases. Each phase scans through all edges of the graph, and the algorithm tries to produce **relaxation** along each edge ( a , b ) having weight c. Relaxation along the edges is an attempt to improve the value d \[ b \] using value d \[ a \] \+ c. In fact, it means that we are trying to improve the answer for this vertex using edge ( a , b ) and current answer for vertex a.
It is claimed that n − 1 phases of the algorithm are sufficient to correctly calculate the lengths of all shortest paths in the graph (again, we believe that the cycles of negative weight do not exist). For unreachable vertices the distance d \[ \] will remain equal to infinity ∞.
## Implementation[¶](https://cp-algorithms.com/graph/bellman_ford.html#implementation "Permanent link")
Unlike many other graph algorithms, for Bellman-Ford algorithm, it is more convenient to represent the graph using a single list of all edges (instead of n lists of edges - edges from each vertex). We start the implementation with a structure e d g e for representing the edges. The input to the algorithm are numbers n, m, list e of edges and the starting vertex v. All the vertices are numbered 0 to n − 1.
### The simplest implementation[¶](https://cp-algorithms.com/graph/bellman_ford.html#the-simplest-implementation "Permanent link")
The constant I N F denotes the number "infinity" — it should be selected in such a way that it is greater than all possible path lengths.
```
```
The check `if (d[e.a] < INF)` is needed only if the graph contains negative weight edges: no such verification would result in relaxation from the vertices to which paths have not yet found, and incorrect distance, of the type ∞ − 1, ∞ − 2 etc. would appear.
### A better implementation[¶](https://cp-algorithms.com/graph/bellman_ford.html#a-better-implementation "Permanent link")
This algorithm can be somewhat speeded up: often we already get the answer in a few phases and no useful work is done in remaining phases, just a waste visiting all edges. So, let's keep the flag, to tell whether something changed in the current phase or not, and if any phase, nothing changed, the algorithm can be stopped. (This optimization does not improve the asymptotic behavior, i.e., some graphs will still need all n − 1 phases, but significantly accelerates the behavior of the algorithm "on an average", i.e., on random graphs.)
With this optimization, it is generally unnecessary to restrict manually the number of phases of the algorithm to n − 1 — the algorithm will stop after the desired number of phases.
```
```
### Retrieving Path[¶](https://cp-algorithms.com/graph/bellman_ford.html#retrieving-path "Permanent link")
Let us now consider how to modify the algorithm so that it not only finds the length of shortest paths, but also allows to reconstruct the shortest paths.
For that, let's create another array p \[ 0 … n − 1 \], where for each vertex we store its "predecessor", i.e. the penultimate vertex in the shortest path leading to it. In fact, the shortest path to any vertex a is a shortest path to some vertex p \[ a \], to which we added a at the end of the path.
Note that the algorithm works on the same logic: it assumes that the shortest distance to one vertex is already calculated, and, tries to improve the shortest distance to other vertices from that vertex. Therefore, at the time of improvement we just need to remember p \[ \], i.e, the vertex from which this improvement has occurred.
Following is an implementation of the Bellman-Ford with the retrieval of shortest path to a given node t:
```
```
Here starting from the vertex t, we go through the predecessors till we reach starting vertex with no predecessor, and store all the vertices in the path in the list p a t h. This list is a shortest path from v to t, but in reverse order, so we call r e v e r s e ( ) function over p a t h and then output the path.
## The proof of the algorithm[¶](https://cp-algorithms.com/graph/bellman_ford.html#the-proof-of-the-algorithm "Permanent link")
First, note that for all unreachable vertices u the algorithm will work correctly, the label d \[ u \] will remain equal to infinity (because the algorithm Bellman-Ford will find some way to all reachable vertices from the start vertex v, and relaxation for all other remaining vertices will never happen).
Let us now prove the following assertion: After the execution of i t h phase, the Bellman-Ford algorithm correctly finds all shortest paths whose number of edges does not exceed i.
In other words, for any vertex a let us denote the k number of edges in the shortest path to it (if there are several such paths, you can take any). According to this statement, the algorithm guarantees that after k t h phase the shortest path for vertex a will be found.
**Proof**: Consider an arbitrary vertex a to which there is a path from the starting vertex v, and consider a shortest path to it ( p 0 \= v , p 1 , … , p k \= a ). Before the first phase, the shortest path to the vertex p 0 \= v was found correctly. During the first phase, the edge ( p 0 , p 1 ) has been checked by the algorithm, and therefore, the distance to the vertex p 1 was correctly calculated after the first phase. Repeating this statement k times, we see that after k t h phase the distance to the vertex p k \= a gets calculated correctly, which we wanted to prove.
The last thing to notice is that any shortest path cannot have more than n − 1 edges. Therefore, the algorithm sufficiently goes up to the ( n − 1 ) t h phase. After that, it is guaranteed that no relaxation will improve the distance to some vertex.
## The case of a negative cycle[¶](https://cp-algorithms.com/graph/bellman_ford.html#the-case-of-a-negative-cycle "Permanent link")
Everywhere above we considered that there is no negative cycle in the graph (precisely, we are interested in a negative cycle that is reachable from the starting vertex v, and, for an unreachable cycles nothing in the above algorithm changes). In the presence of a negative cycle(s), there are further complications associated with the fact that distances to all vertices in this cycle, as well as the distances to the vertices reachable from this cycle is not defined — they should be equal to minus infinity ( − ∞ ).
It is easy to see that the Bellman-Ford algorithm can endlessly do the relaxation among all vertices of this cycle and the vertices reachable from it. Therefore, if you do not limit the number of phases to n − 1, the algorithm will run indefinitely, constantly improving the distance from these vertices.
Hence we obtain the **criterion for presence of a cycle of negative weights reachable for source vertex v**: after ( n − 1 ) t h phase, if we run algorithm for one more phase, and it performs at least one more relaxation, then the graph contains a negative weight cycle that is reachable from v; otherwise, such a cycle does not exist.
Moreover, if such a cycle is found, the Bellman-Ford algorithm can be modified so that it retrieves this cycle as a sequence of vertices contained in it. For this, it is sufficient to remember the last vertex x for which there was a relaxation in n t h phase. This vertex will either lie on a negative weight cycle, or is reachable from it. To get the vertices that are guaranteed to lie on a negative cycle, starting from the vertex x, pass through to the predecessors n times. In this way, we will get to the vertex y, which is guaranteed to lie on a negative cycle. We have to go from this vertex, through the predecessors, until we get back to the same vertex y (and it will happen, because relaxation in a negative weight cycle occur in a circular manner).
### Implementation:[¶](https://cp-algorithms.com/graph/bellman_ford.html#implementation_1 "Permanent link")
```
```
Due to the presence of a negative cycle, for n iterations of the algorithm, the distances may go far in the negative range (to negative numbers of the order of − n m W, where W is the maximum absolute value of any weight in the graph). Hence in the code, we adopted additional measures against the integer overflow as follows:
```
d[e.b] = max(-INF, d[e.a] + e.cost);
```
The above implementation looks for a negative cycle reachable from some starting vertex v; however, the algorithm can be modified to just look for any negative cycle in the graph. For this we need to put all the distance d \[ i \] to zero and not infinity — as if we are looking for the shortest path from all vertices simultaneously; the validity of the detection of a negative cycle is not affected.
For more on this topic — see separate article, [Finding a negative cycle in the graph](https://cp-algorithms.com/graph/finding-negative-cycle-in-graph.html).
## Shortest Path Faster Algorithm (SPFA)[¶](https://cp-algorithms.com/graph/bellman_ford.html#shortest-path-faster-algorithm-spfa "Permanent link")
SPFA is a improvement of the Bellman-Ford algorithm which takes advantage of the fact that not all attempts at relaxation will work. The main idea is to create a queue containing only the vertices that were relaxed but that still could further relax their neighbors. And whenever you can relax some neighbor, you should put him in the queue. This algorithm can also be used to detect negative cycles as the Bellman-Ford.
The worst case of this algorithm is equal to the O ( n m ) of the Bellman-Ford, but in practice it works much faster and some [people claim that it works even in O ( m ) on average](https://en.wikipedia.org/wiki/Shortest_Path_Faster_Algorithm#Average-case_performance). However be careful, because this algorithm is deterministic and it is easy to create counterexamples that make the algorithm run in O ( n m ).
There are some care to be taken in the implementation, such as the fact that the algorithm continues forever if there is a negative cycle. To avoid this, it is possible to create a counter that stores how many times a vertex has been relaxed and stop the algorithm as soon as some vertex got relaxed for the n\-th time. Note, also there is no reason to put a vertex in the queue if it is already in.
```
```
A list of tasks that can be solved using the Bellman-Ford algorithm:
- [E-OLYMP \#1453 "Ford-Bellman" \[difficulty: low\]](https://www.e-olymp.com/en/problems/1453)
- [UVA \#423 "MPI Maelstrom" \[difficulty: low\]](http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=364)
- [UVA \#534 "Frogger" \[difficulty: medium\]](http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=7&page=show_problem&problem=475)
- [UVA \#10099 "The Tourist Guide" \[difficulty: medium\]](http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=12&page=show_problem&problem=1040)
- [UVA \#515 "King" \[difficulty: medium\]](http://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=456)
- [UVA 12519 - The Farnsworth Parabox](https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3964)
See also the problem list in the article [Finding the negative cycle in a graph](https://cp-algorithms.com/graph/finding-negative-cycle-in-graph.html). \* [CSES - High Score](https://cses.fi/problemset/task/1673) \* [CSES - Cycle Finding](https://cses.fi/problemset/task/1197)
- - [bimalkant-lauhny](https://github.com/bimalkant-lauhny "bimalkant-lauhny") (53.11%)
- [wangwillian0](https://github.com/wangwillian0 "wangwillian0") (17.95%)
- [jakobkogler](https://github.com/jakobkogler "jakobkogler") (16.12%)
- [likecs](https://github.com/likecs "likecs") (3.66%)
- [adamant-pwn](https://github.com/adamant-pwn "adamant-pwn") (2.57%)
- [RodionGork](https://github.com/RodionGork "RodionGork") (2.56%)
- [aryamanjain-scifin](https://github.com/aryamanjain-scifin "aryamanjain-scifin") (0.73%)
- [aleksmish](https://github.com/aleksmish "aleksmish") (0.37%)
- [joaomarcosth9](https://github.com/joaomarcosth9 "joaomarcosth9") (0.37%)
- [Aman-Codes](https://github.com/Aman-Codes "Aman-Codes") (0.37%)
- [orendon](https://github.com/orendon "orendon") (0.37%)
- [DiegoHDMGZ](https://github.com/DiegoHDMGZ "DiegoHDMGZ") (0.37%)
- [pirateksh](https://github.com/pirateksh "pirateksh") (0.37%)
- [sachinpatel9135](https://github.com/sachinpatel9135 "sachinpatel9135") (0.37%)
- [prprprpony](https://github.com/prprprpony "prprprpony") (0.37%)
- [Morass](https://github.com/Morass "Morass") (0.37%) |
| Shard | 24 (laksa) |
| Root Hash | 3318995594040849224 |
| Unparsed URL | com,cp-algorithms!/graph/bellman_ford.html s443 |