Bellman Ford Algorithm Negative Weights in DSA Typescript - Time & Space Complexity
We want to understand how the Bellman Ford algorithm's running time changes as the graph size grows.
Specifically, how does the number of edges and vertices affect the work done?
Analyze the time complexity of the following code snippet.
function bellmanFord(edges: [number, number, number][], V: number, src: number): number[] {
const dist = Array(V).fill(Infinity);
dist[src] = 0;
for (let i = 0; i < V - 1; i++) {
for (const [u, v, w] of edges) {
if (dist[u] !== Infinity && dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
}
}
}
return dist;
}
This code finds shortest paths from a source to all vertices, even with negative weights, by relaxing edges repeatedly.
- Primary operation: The inner loop that checks and updates distances for all edges.
- How many times: This inner loop runs once for every edge, repeated (V - 1) times where V is the number of vertices.
As the number of vertices (V) and edges (E) grow, the total operations grow roughly by E times V.
| Input Size (V, E) | Approx. Operations |
|---|---|
| V=10, E=20 | About 10 * 20 = 200 |
| V=100, E=500 | About 100 * 500 = 50,000 |
| V=1000, E=2000 | About 1000 * 2000 = 2,000,000 |
Pattern observation: Operations grow linearly with edges and vertices multiplied together.
Time Complexity: O(V * E)
This means the time needed grows proportionally to the number of vertices times the number of edges.
[X] Wrong: "The algorithm runs in O(E) time because it just loops over edges."
[OK] Correct: The edge loop runs multiple times--once for each vertex minus one--so total work multiplies by V.
Understanding this time complexity helps you explain why Bellman Ford is slower than other shortest path methods but necessary for graphs with negative weights.
"What if we stopped the algorithm early when no distances change in an iteration? How would that affect the time complexity?"
Practice
Solution
Step 1: Understand the limitation of Dijkstra's algorithm
Dijkstra's algorithm cannot correctly handle graphs with negative weight edges because it assumes that once a node's shortest path is found, it cannot be improved.Step 2: Identify Bellman-Ford's capability
Bellman-Ford algorithm can handle negative weight edges and detect negative weight cycles, making it more versatile for such graphs.Final Answer:
It can handle graphs with negative weight edges. -> Option CQuick Check:
Negative weights handled = A [OK]
- Thinking Bellman-Ford is always faster
- Believing it uses less memory
- Assuming it only works on acyclic graphs
Solution
Step 1: Initialize distances with Infinity
We start with all distances as Infinity to represent unknown paths, except the source which is 0.Step 2: Correct syntax for array initialization
Using new Array(n).fill(Infinity) creates an array of size n filled with Infinity, then setting dist[source] = 0 sets the source distance correctly.Final Answer:
const dist = new Array(n).fill(Infinity); dist[source] = 0; -> Option AQuick Check:
Initialize with Infinity except source 0 = C [OK]
- Filling with 0 instead of Infinity
- Setting source distance to Infinity
- Using -Infinity which is incorrect
for (const [u, v, w] of edges) {
if (dist[u] !== Infinity && dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
}
}
console.log(dist);
If edges = [[0,1,4],[1,2,-2],[0,2,5]] and initial dist = [0, Infinity, Infinity], what will be the output after this iteration?Solution
Step 1: Relax edge (0,1,4)
dist[0] = 0, 0 + 4 = 4 < dist[1] (Infinity), so dist[1] = 4.Step 2: Relax edge (1,2,-2)
dist[1] = 4, 4 + (-2) = 2 < dist[2] (Infinity), so dist[2] = 2.Step 3: Relax edge (0,2,5)
dist[0] = 0, 0 + 5 = 5 < dist[2] (2)? No, so no update.Final Answer:
[0, 4, 2] -> Option DQuick Check:
Relax edges updates dist to [0,4,2] [OK]
- Not updating dist[2] after second edge
- Updating dist[2] incorrectly on last edge
- Ignoring initial Infinity checks
for (const [u, v, w] of edges) {
if (dist[u] + w < dist[v]) {
console.log('Negative cycle detected');
}
}
What is the bug in this code snippet?Solution
Step 1: Understand the condition for negative cycle detection
After all relaxation rounds, if any edge can still relax dist[v], a negative cycle exists.Step 2: Identify missing Infinity check
If dist[u] is Infinity (unreachable), dist[u] + w is invalid and can cause wrong detection or runtime error.Final Answer:
It does not check if dist[u] is Infinity before comparison. -> Option AQuick Check:
Check dist[u] !== Infinity before comparing [OK]
- Forgetting to check dist[u] Infinity
- Trying to update dist[v] in detection phase
- Misplacing detection inside main loop
Solution
Step 1: Identify the cycle and its weight
The cycle 1->2->3->1 has weights 1->2 (-1), 2->3 (-1), 3->1 (-1), total -3, which is negative.Step 2: Bellman-Ford detects negative cycles
After |V|-1 iterations, if any edge can still relax distances, it means a negative cycle exists.Step 3: Result of running Bellman-Ford
The algorithm will detect the negative cycle and report it instead of giving shortest distances.Final Answer:
Negative cycle detected because the cycle 1->2->3->1 sums to -3. -> Option BQuick Check:
Negative cycle sum < 0 means detection = D [OK]
- Ignoring negative cycle and reporting distances
- Assuming algorithm runs infinitely
- Miscomputing cycle weight
Ready to prove it?
Pass the test and this pattern moves unknown
