## 4.2 Dijkstra's Algorithm for Single-Source Shortest Paths
In [Section 3.2](LiB0031.html#350), we developed a θ(*n*3) algorithm for determining the shortest paths from each vertex to all other vertices in a weighted, directed graph. If we wanted to know only the shortest paths from one paticular vertex to all the others, that algorithm would be overkill. Next we will use the greedy approach to develop a θ(*n*2) algorithm for this problem (called the Single Source Shortest Paths problem). This algorithm is due to Dijkstra (1959). We present the algorithm, assuming that there is a path from the vertex of interest to each of the other vertices. It is a simple modification to handle the case where this is not so.
This algorithm is similar to Prim's algorithm for the Minimum Spanning Tree problem. We initialize a set *Y* to contain only the vertex whose shortest paths are to be determined. For focus, we say that the vertex is *v*1. We initialize a set *F* of edges to being empty. First we choose a vertex *v* that is nearest to *v*1, add it to *Y*, and add the edge <*v*1, *v*> to *F*. (By < *v*1, *v* > we mean the directed edge from *v*1 to *v*.) That edge is clearly a shortest path from *v*1 to *v*. Next we check the paths from *v*1 to the vertices in *V* - *Y* that allow only vertices in *Y* as intermediate vertices. A shortest of these paths is a shortest path (this needs to be proven). The vertex at the end of such a path is added to *Y*, and the edge (on the path) that touches that vertex is added to *F*. This procedure is continued until *Y* equals *V*, the set of all vertices. At this point, *F* contains the edges in shortest paths. The following is a high-level algorithm for this apporoach.
```
Y = {v1};
F = Ø
while (the instance is not solved) {
select a vertex v from V - Y, that has a // selection
shortest path from v1, using only vertices in // procedure and
in Y as intermediates; // feasibility check
add the new vertex v to Y;
add the edge (on the shortest path) that touches v to F;
if (Y == V)
the instance is solved; // solution check
}
```
[Figure 4.8](#ch04fig08) illustrates Dijkstra's algorithm. As was the case for Prim's algorithm, the high-level algorithm works only for a human solving an instance by inspection on a small graph. Next we give a detailed algorithm. For this algorithm, the weighted graph is represented by a two-dimensional array exactly as was done in [Section 3.2](LiB0031.html#350). This algorithm is very similar to [Algorithm 4.1](LiB0033.html#378) (Prim's). The difference is that instead of the arrays *nearest* and *distance*, we have arrays *touch* and *length*, where for *i* = 2, …, *n*,
[](fig4-8_0.jpg)
Figure 4.8: A weighted, directed graph (in upper-left corner) and the steps in Dijkstra's algorithm for that graph. The vertices in *Y* and the edges in *F* are shaded in color at each step.
*touch\[i\]* = index of vertex *v* in *Y* such that the edge <*v*, *vi*> is the last edge on the current shortest path from *v*1 to *vi* using only vertices in *Y* as intermediates.
*length\[i\]* = length of the current shortest path from *v*1 to *v*i using only vertices in *Y* as intermediates.
The algorithm follows.
Algorithm 4.3: Dijkstra's Algorithm****Problem: Determine the shortest paths from *v*1 to all other vertices in a weighted, directed graph.
Inputs: integer *n* ≥ 2, and a connected, weighted, directed graph containing *n* vertices. The graph is represented by a two-dimensional array *W*, which has both its rows and columns indexed from 1 to *n*, where *W\[i\]\[j\]* is the weight on the edge from the *i*th vertex to the *j*th vertex.
Outputs: set of edges *F* containing edges in shortest paths.
```
void dijkstra (int n,
const number W[][],
set_of_edges&F)
{
index i, unear;
edge e;
index touch [2 .. n];
number length [2 .. n];
F = Ø;
for (i = 2; i<= n; i++){ // For all vertices, initialize v1touch [i] = 1; // to be the last vertex on the
length [i] = W[1] [i]; // current shortest path from
} // v1, and initialize length of
// that path to be the weight
// on the edge from v1.
repeat (n - 1 times){ // Add all n - 1 vertices to Y.
min = ∞;
for (i = 2; i < = n; i++) // Check each vertex for
if ( 0 ≤ length [i] < min) { // having shortest path.
min = length [i];
unear = i;
}
e = edge from vertex indexed by touch [vnear]
to vertex indexed by vnear;
add e to F;
for (i = 2; i < = n; i++)
if (length [vnear] + W[vnear] [i] < length [i]){
length[i] = length[vnear] + W[vnear][i];
touch[i] = vnear; // For each vertex not in Y,
} // update its shortest path.
length[vnear] = -1; // Add vertex indexed by vnear
} // to Y.
}
```
****
Because we are assuming that there is a path from *v*1 to every other vertex, the variable *vnear* has a new value in each iteration of the **repeat** loop. If this were not the case, the algorithm, as written, would end up adding the last edge over and over until *n* - 1 iterations of the **repeat** loop were completed.
[Algorithm 4.3](#ch04ex08) determines only the edges in the shortest paths. It does not produce the lengths of those paths. These lengths could be obtained from the edges. Alternatively, a simple modification of the algorithm would enable it to compute the lengths and store them in an array as well.
The control in [Algorithm 4.3](#ch04ex08) is identical to that in [Algorithm 4.1](LiB0033.html#378). Therefore, from the analysis of that [Algorithm 4.1](LiB0033.html#378), we know for [Algorithm 4.3](#ch04ex08) that

Although we do not do it here, it is possible to prove that [Algorithm 4.3](#ch04ex08) always produces shortest paths. The proof uses an induction argument similar to the one used to prove that Prim's algorithm ([Algorithm 4.1](LiB0033.html#378)) always produces a minimum spanning tree.
As is the case for Prim's algorithm, Dijkstra's algorithm can be implemented using a heap or a Fibonacci heap. The heap implementation is θ (*m* lg *n*), and the Fibonacci heap implementation is θ(*m + n* lg *n*), where *m* is the number of edges. See Fredman and Tarjan (1987) for this latter implementation.
- Table of Contents
- BackCover
- Foundations of Algorithms Using C++ Pseudocode, Third Edition
- Preface
- Chapter Contents
- Pedagogy
- Course Outlines
- Acknowledgments
- Errors
- Chapter 1: Algorithms - Efficiency, Analysis, and Order
- 1.2 The Importance of Developing Efficient Algorithms
- 1.3 Analysis of Algorithms
- 1.4 Order
- 1.5 Outline of This Book
- Exercises
- Chapter 2: Divide-and-Conquer
- 2.1 Binary Search
- 2.2 Mergesort
- 2.3 The Divide-and-Conquer Approach
- 2.4 Quicksort (Partition Exchange Sort)
- 2.5 Strassen's Matrix Multiplication Algorithm
- 2.6 Arithmetic with Large Integers
- 2.7 Determining Thresholds
- 2.8 When Not to Use Divide-and-Conquer
- Exercises
- Chapter 3: Dynamic Programming
- 3.1 The Binomial Coefficient
- 3.2 Floyd's Algorithm for Shortest Paths
- 3.3 Dynamic Programming and Optimization Problems
- 3.4 Chained Matrix Multiplication
- 3.5 Optimal Binary Search Trees
- 3.6 The Traveling Salesperson Problem
- Exercises
- Chapter 4: The Greedy Approach
- 4.1 Minimum Spanning Trees
- 4.2 Dijkstra's Algorithm for Single-Source Shortest Paths
- 4.3 Scheduling
- 4.4 Huffman Code
- 4.5 The Greedy Approach versus Dynamic Programming: The Knapsack Problem
- Exercises
- Chapter 5: Backtracking
- 5.2 The n-Queens Problem
- 5.3 Using a Monte Carlo Algorithm to Estimate the Efficiency of a Backtracking Algorithm
- 5.4 The Sum-of-Subsets Problem
- 5.5 Graph Coloring
- 5.6 The Hamiltonian Circuits Problem
- 5.7 The 0-1 Knapsack Problem
- Exercises
- Chapter 6: Branch-and-Bound
- 6.1 Illustrating Branch-and-Bound with the 0 - 1 Knapsack problem
- 6.2 The Traveling Salesperson Problem
- 6.3 Abductive Inference (Diagnosis)
- Exercises
- Chapter 7: Introduction to Computational Complexity - The Sorting Problem
- 7.2 Insertion Sort and Selection Sort
- 7.3 Lower Bounds for Algorithms that Remove at Most One Inversion per Comparison
- 7.4 Mergesort Revisited
- 7.5 Quicksort Revisited
- 7.6 Heapsort
- 7.6.1 Heaps and Basic Heap Routines
- 7.6.2 An Implementation of Heapsort
- 7.7 Comparison of Mergesort, Quicksort, and Heapsort
- 7.8 Lower Bounds for Sorting Only by Comparison of Keys
- 7.8.1 Decision Trees for Sorting Algorithms
- 7.8.2 Lower Bounds for Worst-Case Behavior
- 7.8.3 Lower Bounds for Average-Case Behavior
- 7.9 Sorting by Distribution (Radix Sort)
- Exercises
- Chapter 8: More Computational Complexity - The Searching Problem
- 8.1 Lower Bounds for Searching Only by Comparisons of Keys
- 8.2 Interpolation Search
- 8.3 Searching in Trees
- 8.4 Hashing
- 8.5 The Selection Problem: Introduction to Adversary Arguments
- Exercises
- Chapter 9: Computational Complexity and Interactability - An Introduction to the Theory of NP
- 9.2 Input Size Revisited
- 9.3 The Three General Problem Categories
- 9.4 The Theory of NP
- 9.5 Handling NP-Hard Problems
- Exercises
- Chapter 10: Number-Theoretic Algorithms
- 10.1 Number Theory Review
- 10.2 Computing the Greatest Common Divisor
- 10.3 Modular Arithmetic Review
- 10.4 Solving Modular Linear Equations
- 10.5 Computing Modular Powers
- 10.6 Finding Large Prime Numbers
- 10.7 The RSA Public-Key Cryptosystem
- Exercises
- Chapter 11: Introduction to Parallel Algorithms
- 11.1 Parallel Architectures
- 11.2 The PRAM Model
- Exercises
- Appendix A: Review of Necessary Mathematics
- A.2 Functions
- A.3 Mathematical Induction
- A.4 Theorems and Lemmas
- A.5 Logarithms
- A.6 Sets
- A.7 Permutations and Combinations
- A.8 Probability
- Exercises
- Appendix B: Solving Recurrence Equations - With Applications to Analysis of Recursive Algorithms
- B.2 Solving Recurrences Using the Characteristic Equation
- B.3 Solving Recurrences by Substitution
- B.4 Extending Results for n, a Power of a Positive Constant b, to n in General
- B.5 Proofs of Theorems
- Exercises
- Appendix C: Data Structures for Disjoint Sets
- References
- Index
- Index_B
- Index_C
- Index_D
- Index_E
- Index_F
- Index_G
- Index_H
- Index_I
- Index_J
- Index_K
- Index_L
- Index_M
- Index_N
- Index_O
- Index_P
- Index_Q
- Index_R
- Index_S
- Index_T
- Index_U
- Index_V
- Index_W-X
- Index_Y
- Index_Z
- List of Figures
- List of Tables
- List of Algorithms, Examples, and Theorems
- List of Sidebars