Dijkstra
Dijkstra's original algorithm found the shortest path between two given nodes, but a more common variant fixes a single node as the "source" node and finds shortest paths from the source to all other nodes in the graph, producing a shortest-path tree.
It's a greedy BFS algorithm.
It does NOT support negative edge.
Note that we should only use this algorithm on a weighted graph. If it's an unweighted graph, just use BFS.
Algorithm
Summary: Use heap to store the cost of nodes. Each time pop the heap top node, whose shortest path is determimed once popped, and use its outbound edges to relax its neighbors and push the relaxed neighbors into the heap.
Given V
vertices and E
edges. The all weights of all edges are non-negative. Find the smallest distance from a source node S
to all other nodes.
We split the V
vertices into two sets:
A
, visited nodes, i.e. those whose shortest path is already determined.B
, unvisited nodes.
Initially:
A
is empty andB
contains all the verticesThe distance of the source vertex is
0
, andInfinity
for all other vertices.
Then we keep the following operations until all vertices are visited:
Find the vertice with the smallest distance from
B
, sayu
. Moveu
fromB
toA
.For each outbound edge from
u
(u, v, w)
(v
is the destination verte,w
is the weight), try to relaxv
usingu
andw
-- Ifdist[v] > dist[u] + w
, thendist[v] = dist[u] + w
.
Why no negative edge?
Dijkstra is a greedy algorithm. If all the edges are non-negative, once we find the node with the smallest cost from unvisited vertice set, say u
, we are sure that it won't be updated later -- it's already the optimal path.
But if there are negative edges, this u
can be updated again later using negative edge.
Implementation
Here I only talk about the solution using priority_queue
.
Let pq
be a priority_queue
of pairs of the cost (i.e. the length of the shortest path from src
) and the vertex index. The element with the smallest cost is at the top of the queue (i.e. min-heap). Initially pq
only has (0, src)
in it.
Let dist[u]
be the cost of u
. Initially dist[src] = 0
and dist[u] = INF
for all other vertices.
When the same node has been relaxed multiple times, we should delete the old relaxations from the priority queue. But with priority_queue
, we don't have a way to do it. So we just push the entry of the same node and smaller cost into the priority queue.
When a node is popped from the queue and it's already visited, then we should skip it.
Time complexity analysis: In the worst case, each visited node will push new items into the priority queue using all its outbound edges. So there will be O(E)
items in the priority queue in total. The overall time complexity is Elog(E)
.
If we can use Fabonacci Heap, the time complexity will be reduced to O(E + VlogV)
.
Another way to prevent visiting the same node twice is as follows:
Problems
Reference
Last updated