Minimum Transportation Cost (Naive 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.
Your task is to find the minimum transportation cost from city 1 to city n after considering all government subsidies.
If the minimum transportation cost is negative, it means that transportation generates a net profit.
It is possible that city n cannot be reached from city 1.
The road network is guaranteed to contain no negative-weight cycles.
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 the minimum cost is negative, it represents the amount of profit generated after government subsidies.
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 does not 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 graphs containing negative edge weights.
Unlike Dijkstra, Bellman-Ford does not require all edge weights to be non-negative.
Original study notes follow, including intermediate snippets and earlier attempts.
Approach: Naive Bellman-Ford¶
Bellman-Ford is a shortest-path algorithm that can handle graphs containing negative edge weights.
Unlike Dijkstra, Bellman-Ford does not require all edge weights to be non-negative.
Its core idea is simple:
Repeatedly scan every edge and try to improve the shortest distance to each node.
This operation is called relaxation.
Define minCost¶
Let:
represent:
The minimum transportation cost currently known from city
1to cityi.
Initially, all cities are considered unreachable:
The starting city has cost 0:
So initially:
Relax an Edge¶
Suppose there is a directed edge:
If we already know the shortest cost to reach u, then traveling through this edge gives a possible cost to reach v:
If:
then we found a cheaper path to v.
So we update:
The full condition is:
Why Check minCost[u] != inf?¶
Suppose city u has never been reached from city 1.
Then:
In that case, we cannot use the edge:
because there is currently no valid path from city 1 to u.
Therefore we only perform relaxation when:
Why Relax All Edges n - 1 Times?¶
There are n cities.
If the graph contains no negative-weight cycle, a shortest path never needs to repeatedly visit the same node.
Therefore, a shortest simple path can contain at most:
which means at most:
For example:
contains 5 nodes and 4 edges.
Therefore Bellman-Ford performs at most:
full scans of all edges.
After these scans, all shortest distances are guaranteed to be found if there is no reachable negative cycle.
Why Do We Scan Every Edge?¶
Bellman-Ford works directly on the edge list.
For every iteration:
we check whether the edge:
can improve:
Unlike Dijkstra, Bellman-Ford does not permanently finalize a node.
A node's distance may be updated multiple times.
This is why Bellman-Ford can handle negative edges.
Example of Relaxation¶
Consider:
Initially:
Using:
we get:
Using:
we get:
Then using:
we get:
Since:
we update:
So the shortest path is:
with total cost:
In-Place Updates¶
In this implementation, minCost is updated directly during each iteration.
For example, suppose the edges appear in this order:
During one full scan:
1 → 2
↓
update minCost[2]
2 → 3
↓
use the newly updated minCost[2]
↓
update minCost[3]
3 → 4
↓
use the newly updated minCost[3]
↓
update minCost[4]
Therefore, one iteration may propagate shortest-path information across multiple edges.
Because of this:
n - 1iterations are a safe upper bound, but Bellman-Ford may converge earlier depending on the edge order.
Why Can Bellman-Ford Handle Negative Edges?¶
Dijkstra relies on the assumption that once the currently closest node is selected, its shortest distance will never decrease again.
This is not true when negative edges exist.
For example:
Initially we may find:
but later:
So the distance to city 3 changes:
Bellman-Ford allows this because nodes can be relaxed repeatedly.
Why Is There No Negative Cycle Detection Here?¶
This problem guarantees:
Therefore we only need to calculate the shortest paths.
We do not need the additional Bellman-Ford pass used for negative-cycle detection.
If negative cycles were allowed, we would perform one additional scan after the n - 1 iterations.
If any edge could still be relaxed, that would indicate a reachable negative cycle.
Final Answer¶
We only care about the shortest path:
So after Bellman-Ford finishes, check:
If:
then city n is unreachable from city 1.
Return:
Otherwise:
Bellman-Ford Process Summary¶
Initialize minCost
↓
minCost[1] = 0
↓
Repeat n - 1 times
↓
Scan every edge
↓
For each edge u → v
↓
Can minCost[u] + w improve minCost[v]?
↓
Yes
↓
Update minCost[v]
↓
Continue
↓
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.
Bellman-Ford¶
Bellman-Ford allows:
A node's shortest distance may change multiple times.
Bellman-Ford repeatedly scans edges and performs relaxation until shortest distances are obtained.
Bellman-Ford vs SPFA¶
Naive Bellman-Ford¶
Repeatedly scans all edges:
SPFA¶
Uses a queue and mainly processes nodes whose shortest distances have changed:
SPFA may avoid unnecessary edge scans in practice.
However, both have worst-case complexity:
Complexity¶
Let:
Time Complexity¶
Bellman-Ford performs at most:
iterations.
Each iteration scans:
edges.
Therefore:
Space Complexity¶
We only need:
which stores one value for each city.
Therefore:
Bellman-Ford does not require an adjacency list because it directly scans the edge list.
Optional Optimization¶
We can use an updated flag.
If one complete iteration does not update any distance, then all shortest distances are already stable.
So we can stop early:
for _ in range(n - 1):
updated = False
for u, v, w in roads:
if (
minCost[u] != float('inf')
and minCost[v] > minCost[u] + w
):
minCost[v] = minCost[u] + w
updated = True
if not updated:
break
This does not change the worst-case complexity, but it may reduce unnecessary iterations.
Key Takeaways¶
The core of Bellman-Ford is relaxation:
Try:
The most important ideas are:
Negative edges are allowed.
Scan all edges repeatedly.
At most n - 1 full scans are required.
A node's shortest distance may be updated multiple times.
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):
updated = False
for u, v, w in roads:
if (
minCost[u] != float('inf')
and minCost[v] > minCost[u] + w
):
minCost[v] = minCost[u] + w
updated = True
# 如果已经不往更小的值更新了,那就是找到最小路径了,退出迭代
if not updated:
break
return 'unconnected' if minCost[n] == float('inf') else minCost[n]