Shortest path algorithms are fundamental tools in computer science and graph theory, used to find a path between two vertices (or nodes) in a graph such that the sum of the weights of its constituent edges is minimized. These algorithms have wide-ranging applications, from GPS navigation and network routing to resource allocation and logistics.
A weighted graph is a graph where each edge has an associated numerical weight or cost . This weight can represent distance, time, monetary cost, or any other quantifiable metric. The length of a path in a weighted graph is the sum of the weights of its constituent edges:
The shortest path problem aims to find a path between two specified vertices whose length is minimized. There are two primary variants of this problem:
Dijkstra's Algorithm is a greedy algorithm that solves the Single-Source Shortest Path problem for a graph with non-negative edge weights. It produces a shortest path tree from the source vertex to all other reachable vertices.
Dijkstra's algorithm maintains a set of vertices for which the shortest path from the source has already been finalized. For all other vertices , it maintains a dist[v] value, which is an upper bound on the shortest path distance from the source to . Initially, dist[s] is 0 and all other are .
dist[s] = 0 for the source vertex and `dist[v] = \inftyv \in V$.dist values.dist value from the priority queue.
b. Add to the set of visited vertices (meaning its shortest path has been finalized).
c. For each neighbor of :
i. If is not in and , update and update 's priority in the queue.Consider the following weighted directed graph:
10
s ----> u
| ^
5| |1
v |
| y
2| |9
x ----> v
<---- |4
6 zNote: The diagram provided in the source was slightly ambiguous with edges and . Assuming it's with weight 6 and with weight 2 based on the example. Let's adjust to match standard examples, assuming no edge with 6, but with 2 and with 4. And let be 5. Let's use the provided textual example more directly:
Initial state: dist = {s:0, u:inf, v:inf, x:inf, y:inf}. Priority queue PQ = {(s,0), (u,inf), (v,inf), (x,inf), (y,inf)}.
Extract s (dist=0).
s: u (weight 10), v (weight 5).dist[u] = min(inf, dist[s] + 10) = 10. Update PQ.dist[v] = min(inf, dist[s] + 5) = 5. Update PQ.dist = {s:0, u:10, v:5, x:inf, y:inf}. PQ = {(v,5), (u,10), (x,inf), (y,inf)}.Extract v (dist=5).
v: u (weight 3), (weight 2).Final shortest paths from s:
s to s: 0s to v: 5 (path )s to x: 7 (path )s to : 8 (path )The time complexity of Dijkstra's algorithm depends on the implementation of the priority queue:
Here's a C++ implementation of Dijkstra's algorithm using std::priority_queue:
#include <iostream>
#include <vector>
#include <queue>
#include <limits> // For numeric_limits
const long long INF = std::numeric_limits<long long>::max();
// Pair represents (distance, vertex_id)
typedef std::pair<long long, int> diPair;
// Dijkstra's algorithm function
std::vector<long long> dijkstra(int V, const std::vector<std::vector<diPair>>& adj, int start_node) {
// dist[i] stores the shortest distance from start_node to i
The Floyd-Warshall Algorithm is a dynamic programming algorithm used to find the shortest paths between all pairs of vertices in a weighted graph. It can handle graphs with negative edge weights, but not negative cycles (as a path length would then approach ).
The algorithm iteratively improves an estimate of the shortest path between all pairs of vertices. It considers all possible intermediate vertices such that a path from to might become shorter by passing through .
Let be the shortest path distance from vertex to vertex using only vertices from the set as intermediate vertices.
Initialize a distance matrix :
Consider a graph with 3 vertices (0, 1, 2) and initial weights: Edges:
Initial Distance Matrix :
0 1 2
0 [0, 3, 8]
1 [5, 0, 2]
2 [1, INF, 0]After (allowing 0 as an intermediate vertex):
:
0 1 2
0 [0, 3, 8]
1 [5, 0, 2]
2 [1, INF, 0]After (allowing 1 as an intermediate vertex):
After considering , the matrix will look something like this (assuming remains for simplicity based on initial state):
:
0 1 2
0 [0, 3, 5]
1 [5, 0, 2]
2 [1, INF, 0]The algorithm continues for .
If after all iterations , for any vertex , , then the graph contains a negative cycle. This is because if a path from to becomes negative, it means a cycle exists where traversing it reduces the total path length, making the concept of a "shortest path" ill-defined (you could traverse it infinitely to get ).
The time complexity of the Floyd-Warshall algorithm is , where is the number of vertices. This is due to the three nested loops, each iterating up to times. The space complexity is to store the distance matrix.
| Feature | Dijkstra's Algorithm | Floyd-Warshall Algorithm | | :------------------- | :------------------------------------ | :------------------------------------ | | Problem Type | Single-Source Shortest Path (SSSP) | All-Pairs Shortest Path (APSP) | | Edge Weights | Non-negative only | Can handle negative weights (no neg. cycles) | | Approach | Greedy | Dynamic Programming | | Time Complexity | or | | | | or (for array) | |
Applications:
A graph where each edge has an associated numerical value, often representing cost, distance, or time.
The sum of the weights of all edges forming a path between two vertices in a weighted graph.
The problem of finding the shortest paths from a designated starting vertex to all other reachable vertices in a weighted graph.
A greedy algorithm that efficiently solves the SSSP problem for graphs with non-negative edge weights by iteratively expanding the shortest path tree.
The problem of finding the shortest paths between every pair of vertices in a weighted graph.
A dynamic programming algorithm that solves the APSP problem, capable of handling graphs with negative edge weights (but not negative cycles).
Test your understanding with 5 questions
Which characteristic is essential for a graph when applying shortest path algorithms like Dijkstra's or Floyd-Warshall?
Dijkstra's algorithm is guaranteed to find the correct shortest paths only if which condition is met?
In Dijkstra's algorithm, what data structure is commonly used to efficiently select the unvisited vertex with the smallest tentative distance?
What is a key characteristic of the Floyd-Warshall algorithm?
You need to find the shortest path from a single starting point to all other reachable nodes in a very large network where all connection costs are positive. Which algorithm would be most appropriate and why?
dist[u] + w(u, v) < dist[v]dist[v] = dist[u] + w(u, v)dist[u] = min(10, dist[v] + 3) = min(10, 5+3) = 8. Update PQ.dist[x] = min(inf, dist[v] + 2) = 7. Update PQ.dist = {s:0, u:8, v:5, x:7, y:inf}. PQ = {(x,7), (u,8), (y,inf)}.Extract x (dist=7).
x: y (weight 4).dist[y] = min(inf, dist[x] + 4) = min(inf, 7+4) = 11. Update PQ.dist = {s:0, u:8, v:5, x:7, y:11}. PQ = {(u,8), (y,11)}.Extract u (dist=8).
u: y (weight 9), v (weight 1).v is already visited.dist[y] = min(11, dist[u] + 9) = min(11, 8+9) = 11. (No change, ).dist = {s:0, u:8, v:5, x:7, y:11}. PQ = {(y,11)}.Extract y (dist=11).
dist = {s:0, u:8, v:5, x:7, y:11}. PQ is empty.us to y: 11 (path )For each vertex from to (where serves as an intermediate vertex): a. For each source vertex from to : b. For each destination vertex from to : c. Update .
dist6 Modules
6 Modules