Minimum Transportation Cost (Negative Cycles, Bellman-Ford)¶
Edited by Charles
Medium · Python · Graph
Problem
A country wants to promote economic exchange between cities by providing subsidies for cargo transportation.
There are n cities numbered from 1 to n. The cities are connected by a network of directed roads, meaning that a road from city u to city v cannot necessarily be traveled in the opposite direction.
Each road has a transportation cost and a government subsidy. The final weight of a road is calculated as:
Weight = Transportation Cost - Government Subsidy
A positive weight means that transportation still costs money after applying the government subsidy.
A negative weight means that the government subsidy exceeds the transportation cost, so traveling along that road actually generates a profit.
However, the road network may contain negative-weight cycles.
A negative-weight cycle is a cycle whose total edge weight is negative. By repeatedly traveling through such a cycle, the total transportation cost can theoretically be reduced indefinitely.
Your task is to find the minimum transportation cost from city 1 to city n, while also detecting whether a negative-weight cycle exists.
It is also possible that city n cannot be reached from city 1.
Function Signature¶
Parameters¶
n¶
The number of cities.
Cities are numbered:
City 1 is the starting city.
City n is the destination.
roads¶
roads[i] = [u, v, w] represents a directed road from city u to city v with weight w.
The weight w may be:
- Positive
- Zero
- Negative
Return Value¶
Return the minimum transportation cost from city 1 to city n if a valid minimum cost exists.
If the minimum cost is negative, it represents the amount of profit generated after government subsidies.
If a negative-weight cycle is detected, return:
If city n cannot be reached from city 1, return:
Example 1¶
Input¶
Output¶
Example 2¶
Input¶
Output¶
Example 3¶
Input¶
Output¶
Constraints¶
2 <= n1 <= len(roads)roads[i] = [u, v, w]1 <= u, v <= n- The graph is directed.
- Edge weights may be positive, zero, or negative.
- The graph may contain negative-weight cycles.
- Multiple paths may exist between two cities.
- City
nmay be unreachable from city1.
Explanation, examples & other approaches
Core idea
Bellman-Ford is a shortest-path algorithm that can handle:
- Positive edge weights
- Zero edge weights
- Negative edge weights
Original study notes follow, including intermediate snippets and earlier attempts.
Approach: Bellman-Ford + Negative Cycle Detection¶
Bellman-Ford is a shortest-path algorithm that can handle:
- Positive edge weights
- Zero edge weights
- Negative edge weights
Unlike Dijkstra, Bellman-Ford does not require all edge weights to be non-negative.
The core operation is relaxation.
For every edge:
if:
then going from city 1 to u, followed by the edge u → v, gives us a cheaper path to v.
Therefore we update:
Define minCost¶
Let:
represent:
The minimum transportation cost currently known from city
1to cityi.
Initially:
Since the cost of traveling from city 1 to itself is 0:
So initially:
Relax Every Edge¶
Suppose we have an edge:
If city u is already reachable from city 1, then the cost of reaching v through u is:
If this is smaller than the current:
we update it:
The condition:
is important because we can only use the edge:
if city u is reachable from city 1.
Why Relax n - 1 Times?¶
There are n cities.
If there is no negative cycle, a shortest path does not need to repeatedly visit the same node.
Therefore, a shortest simple path can contain at most:
which means it can contain at most:
For example:
If there are 5 nodes on the path, there are 4 edges.
Therefore Bellman-Ford performs:
iterations.
During each iteration, we scan every edge and try to relax it.
Important Note About the n - 1 Iterations¶
In this implementation, minCost is updated in place.
This means a newly updated distance may immediately be used by another edge later in the same iteration.
For example, if the edge order is:
then during just one scan:
1 → 2
↓
update 2
2 → 3
↓
use the new value of 2
↓
update 3
3 → 4
↓
use the new value of 3
↓
update 4
So one iteration may propagate information across multiple edges.
Therefore:
n - 1is a safe upper bound on the number of full edge scans required.
It does not necessarily mean that exactly one additional edge is processed per iteration.
Why Can Bellman-Ford Detect Negative Cycles?¶
This is the most important part of this problem.
If there is no negative cycle, after enough relaxations, all shortest distances eventually become stable.
After performing:
full scans of all edges, there should be no edge that can produce a smaller distance.
In other words, normally:
for every reachable edge.
But suppose after n - 1 iterations we scan all edges one more time and still find:
Then the shortest distance is still decreasing.
That means some path is able to repeatedly reduce its total cost.
This can only happen because there is a reachable negative-weight cycle.
Example of a Negative Cycle¶
Consider:
The total cost of the cycle is:
Every time we travel around this cycle, the total cost decreases by 1.
For example:
Start:
cost = 0
After one cycle:
cost = -1
After two cycles:
cost = -2
After three cycles:
cost = -3
...
Therefore the minimum cost has no lower bound.
It can continue decreasing forever.
Detect the Negative Cycle¶
After the normal n - 1 Bellman-Ford iterations, scan every edge one additional time:
If any edge can still be relaxed:
then return:
The structure is:
Relax all edges n - 1 times
↓
Scan all edges one more time
↓
Can any edge still be relaxed?
↙ ↘
Yes No
↓ ↓
negative cycle continue
↓
"circle"
Why Check minCost[u] != inf When Detecting a Cycle?¶
Consider a negative cycle that exists somewhere else in the graph:
Suppose:
is a negative cycle, but city 1 cannot reach cities 5, 6, or 7.
Then this negative cycle has no effect on paths starting from city 1.
Because:
the condition:
prevents these unreachable edges from being considered.
Therefore, this implementation detects:
Negative cycles that are reachable from city
1.
Final Answer¶
If no reachable negative cycle is found, check:
If:
then city n cannot be reached from city 1.
Return:
Otherwise:
Bellman-Ford Process Summary¶
Initialize minCost
↓
minCost[1] = 0
↓
Repeat n - 1 times
↓
Scan every edge
↓
Try relaxation
↓
After n - 1 iterations
↓
Scan every edge one more time
↓
Can any edge still be relaxed?
↙ ↘
Yes No
↓ ↓
"circle" Check minCost[n]
↙ ↘
inf finite
↓ ↓
"unconnected" minCost[n]
Bellman-Ford vs Dijkstra¶
Dijkstra¶
Dijkstra requires:
Once a node is finalized, its shortest distance will never change again.
Bellman-Ford¶
Bellman-Ford allows:
A node's shortest distance may decrease multiple times.
Therefore Bellman-Ford repeatedly relaxes edges until the distances become stable.
Bellman-Ford vs SPFA¶
Bellman-Ford scans:
during every iteration.
Its basic structure is:
SPFA instead uses a queue and mainly processes nodes whose distances have changed:
So SPFA can avoid some unnecessary edge scans in practice.
However, both algorithms have the same worst-case time complexity:
Complexity¶
Let:
Time Complexity¶
Bellman-Ford performs up to:
iterations.
Each iteration scans:
edges.
The additional negative-cycle check also scans E edges.
Therefore:
Space Complexity¶
We only need:
which contains V values.
Therefore:
No adjacency list is required because Bellman-Ford can directly iterate over the edge list.
Key Takeaways¶
Relaxation¶
For an edge:
try:
Why n - 1?¶
A shortest simple path in a graph with n nodes contains at most:
Negative Cycle Detection¶
The most important rule to remember is:
Relax edges for
n - 1iterations, then scan all edges one more time.
If an edge can still be relaxed:
A useful memory shortcut is:
Study record
| Field | Value |
|---|---|
| Attempts | 1 |
| Mastery | ❚ |
| The Latest Attempt | September 1, 2026 |
Python solution¶
from typing import List
class Solution:
def minimumCost(self, n: int, roads: List[List[int]]):
minCost = [float('inf')] * (n + 1)
minCost[1] = 0
for _ in range(n - 1):
for u, v, w in roads:
if (
minCost[u] != float('inf')
and minCost[v] > minCost[u] + w
):
minCost[v] = minCost[u] + w
# One more iteration to detect a negative cycle
for u, v, w in roads:
if (
minCost[u] != float('inf')
and minCost[v] > minCost[u] + w
):
return 'circle'
return 'unconnected' if minCost[n] == float('inf') else minCost[n]