Shortest Path Algorithms
Finding the shortest path between two points is one of computing's most practical problems. GPS navigation, network routing, game AI pathfinding, and social network analysis all rely on shortest path algorithms. This article covers the four essential algorithms: Dijkstra's for non-negative weights, Bellman-Ford for negative weights, Floyd-Warshall for all pairs, and A* for heuristic-guided search.
๐ At a Glance
| Algorithm | Time | Space | Handles Negative | Best For |
|---|---|---|---|---|
| Dijkstra (binary heap) | O((V+E) log V) | O(V) | No | Single source, non-negative |
| Bellman-Ford | O(VE) | O(V) | Yes (detects cycles) | Negative weights |
| Floyd-Warshall | O(Vยณ) | O(Vยฒ) | Yes (detects cycles) | All pairs, dense graphs |
| A* | O(E) best, O(Vยฒ) worst | O(V) | No | Single pair with heuristic |
๐ฏ What You'll Learn
After reading this article, you will be able to:
- Implement Dijkstra's algorithm with proper priority queue usage
- Handle negative weights using Bellman-Ford
- Compute all-pairs shortest paths with Floyd-Warshall
- Apply A search* with admissible heuristics
- Detect negative cycles that make shortest path undefined
- Choose the right algorithm based on graph characteristics
๐ฅ Production Story: The Logistics Routing Disaster
A delivery company's routing system calculated optimal routes for 500 daily deliveries. After adding "discount roads" with negative costs (toll rebates), the system started producing impossible routes.
JAVA(33 lines)CodeLoading syntax highlighter...
TEXT(12 lines)CodeLoading syntax highlighter...
JAVA(53 lines)CodeLoading syntax highlighter...
๐ง Mental Model: Shortest Path Algorithm Selection
TEXT(23 lines)CodeLoading syntax highlighter...
๐ฌ Deep Dive: Dijkstra's Algorithm
๐ฎ Try It Yourself
Watch Dijkstra's algorithm find shortest paths step by step. Observe how the algorithm greedily selects the minimum distance vertex and relaxes edges:
Loading visualizer...
The Greedy Insight
Dijkstra works by greedily selecting the unvisited vertex with minimum distance. With non-negative weights, this greedy choice is always correct.
TEXT(14 lines)CodeLoading syntax highlighter...
Implementation with Priority Queue
JAVA(98 lines)CodeLoading syntax highlighter...
Dijkstra with Indexed Priority Queue (Optimized)
JAVA(106 lines)CodeLoading syntax highlighter...
๐ฌ Deep Dive: Bellman-Ford Algorithm
Handling Negative Weights
JAVA(110 lines)CodeLoading syntax highlighter...
Why Bellman-Ford Works
TEXT(16 lines)CodeLoading syntax highlighter...
๐ฌ Deep Dive: Floyd-Warshall Algorithm
All-Pairs Shortest Paths
JAVA(112 lines)CodeLoading syntax highlighter...
Floyd-Warshall DP Insight
TEXT(21 lines)CodeLoading syntax highlighter...
๐ฌ Deep Dive: A* Search Algorithm
The Heuristic Advantage
A* uses a heuristic function h(v) to estimate distance from v to goal, prioritizing vertices that seem closer to the goal.
JAVA(75 lines)CodeLoading syntax highlighter...
Common Heuristics
JAVA(35 lines)CodeLoading syntax highlighter...
A* vs Dijkstra Visualization
TEXT(17 lines)CodeLoading syntax highlighter...
๐ฌ Deep Dive: Bidirectional Search
Meeting in the Middle
JAVA(87 lines)CodeLoading syntax highlighter...
โ ๏ธ Common Mistakes
Mistake 1: Using Dijkstra with Negative Weights
JAVA(10 lines)CodeLoading syntax highlighter...
Mistake 2: Integer Overflow in Distance Calculation
JAVA(15 lines)CodeLoading syntax highlighter...
Mistake 3: Not Handling Disconnected Vertices
JAVA(10 lines)CodeLoading syntax highlighter...
Mistake 4: Wrong Heuristic in A*
JAVA(10 lines)CodeLoading syntax highlighter...
๐ Debug This: The Broken Shortest Path
These implementations have bugs. Find and fix them:
JAVA(65 lines)CodeLoading syntax highlighter...
๐ก Hint
Look for:
- Initialization of distances
- Loop count in Bellman-Ford
- Missing negative cycle check
- A* should sort by f-score (g + h), not just g-score
โ Solution
JAVA(84 lines)CodeLoading syntax highlighter...
-
Dijkstra initialization:
dist[i] = graph[src][i]only works if all vertices have direct edges from source. Should initialize to MAX_VALUE and start with source at 0. -
Bellman-Ford iterations: Should be V-1 iterations for relaxation, then one more iteration to detect negative cycles. Original had V iterations and no cycle check.
-
A sorting*: A* must sort by f-score (g + h), not just g-score. Sorting by g-score alone makes it equivalent to Dijkstra, losing the heuristic benefit.
๐ป Exercises
Exercise 1: Network Delay Time (LeetCode 743) โญโญ
Find time for signal to reach all nodes from source.
JAVA(11 lines)CodeLoading syntax highlighter...
Exercise 2: Cheapest Flights Within K Stops (LeetCode 787) โญโญโญ
Find cheapest flight with at most K stops.
JAVA(12 lines)CodeLoading syntax highlighter...
๐ก Hint
Use Bellman-Ford with exactly k+1 iterations (k stops = k+1 edges). Or use BFS with level tracking.
Exercise 3: Path with Maximum Probability (LeetCode 1514) โญโญโญ
Find path with highest probability of success.
JAVA(11 lines)CodeLoading syntax highlighter...
Exercise 4: Shortest Path in Grid with Obstacles (LeetCode 1293) โญโญโญโญ
Find shortest path in grid where you can eliminate up to k obstacles.
JAVA(10 lines)CodeLoading syntax highlighter...
Exercise 5: Find Negative Cycle โญโญโญโญ
Return the actual vertices forming a negative cycle.
JAVA(9 lines)CodeLoading syntax highlighter...
๐ค Interview Questions
Question 1: When would you use each shortest path algorithm?
| Algorithm | Use When |
|---|---|
| BFS | Unweighted graph, need shortest by edge count |
| Dijkstra | Weighted, non-negative, single source |
| A* | Single source-target with good heuristic |
| Bellman-Ford | Has negative weights, need cycle detection |
| Floyd-Warshall | Need all-pairs, dense graph, V is small |
- Negative weights? โ Bellman-Ford or Floyd-Warshall
- Single source or all pairs?
- Graph density (E vs Vยฒ)?
- Have good heuristic? โ Consider A*
Question 2: Why doesn't Dijkstra work with negative weights?
Dijkstra's greedy approach assumes: "Once a vertex is processed, its distance is final."
With negative weights, this assumption breaks:
TEXT(17 lines)CodeLoading syntax highlighter...
Question 3: Explain the A* heuristic requirements
- If h overestimates, A* might skip the optimal path
- Admissible h guarantees optimal solution
- Guarantees A* won't revisit nodes
- All consistent heuristics are admissible
- Manhattan: |dx| + |dy| - admissible for 4-direction grid
- Euclidean: โ(dxยฒ + dyยฒ) - admissible for any movement
- Zero: h(v) = 0 - always admissible, but A* becomes Dijkstra
Question 4: How would you detect a negative cycle?
JAVA(6 lines)CodeLoading syntax highlighter...
JAVA(6 lines)CodeLoading syntax highlighter...
- Track sum of edge weights on current DFS path
- If we return to a vertex with lower total weight, negative cycle found
- Run Bellman-Ford V iterations (not V-1)
- Any vertex updated in V-th iteration is reachable from negative cycle
- Trace back through predecessors to find cycle
Question 5: Compare single-source algorithms complexity
| Algorithm | Time | Space | Notes |
|---|---|---|---|
| BFS | O(V+E) | O(V) | Unweighted only |
| Dijkstra (binary heap) | O((V+E) log V) | O(V) | No negative weights |
| Dijkstra (Fibonacci heap) | O(E + V log V) | O(V) | Better for dense graphs |
| Bellman-Ford | O(VE) | O(V) | Handles negative weights |
| SPFA | O(VE) worst, O(E) avg | O(V) | Optimized Bellman-Ford |
- Sparse graph (E โ V): Dijkstra with binary heap
- Dense graph (E โ Vยฒ): Dijkstra or Bellman-Ford similar
- Need negative weights: Bellman-Ford
- Unweighted: Always use BFS
๐ Quick Reference
Algorithm Comparison
| Dijkstra | Bellman-Ford | Floyd-Warshall | A* | |
|---|---|---|---|---|
| Type | Greedy | DP | DP | Heuristic |
| Negative edges | No | Yes | Yes | No |
| Negative cycles | No | Detects | Detects | No |
| Single source | Yes | Yes | No (all pairs) | Yes |
| Time | O((V+E)log V) | O(VE) | O(Vยณ) | O(E) to O(Vยฒ) |
Code Templates
JAVA(49 lines)CodeLoading syntax highlighter...
๐ Review Schedule
| Day | Focus | Time |
|---|---|---|
| Day 1 | Read article, implement Dijkstra | 60 min |
| Day 3 | Implement Bellman-Ford with cycle detection | 30 min |
| Day 7 | Implement A* for grid pathfinding | 30 min |
| Day 14 | Solve LeetCode shortest path problems | 45 min |
| Day 30 | Review and compare algorithm trade-offs | 20 min |
๐ What's Next?
- Union-Find data structure
- Kruskal's algorithm
- Prim's algorithm
- Borลฏvka's algorithm
- MST applications