# Lecture 17: Dijkstra and Minimum Spanning Trees

### COSC 311 Algorithms, Fall 2022

$\def\compare{ {\mathrm{compare}} } \def\swap{ {\mathrm{swap}} } \def\sort{ {\mathrm{sort}} } \def\insert{ {\mathrm{insert}} } \def\true{ {\mathrm{true}} } \def\false{ {\mathrm{false}} } \def\BubbleSort{ {\mathrm{BubbleSort}} } \def\SelectionSort{ {\mathrm{SelectionSort}} } \def\Merge{ {\mathrm{Merge}} } \def\MergeSort{ {\mathrm{MergeSort}} } \def\QuickSort{ {\mathrm{QuickSort}} } \def\Split{ {\mathrm{Split}} } \def\Multiply{ {\mathrm{Multiply}} } \def\Add{ {\mathrm{Add}} } \def\cur{ {\mathrm{cur}} } \def\gets{ {\leftarrow} }$

## Overview

1. Dijkstra’s Algorithm Correctness
2. Implementing Dijkstra
3. Minimum Spanning Trees

## Last Time: Weighted SSSP

Input.

• a weighted Graph $G = (V, E)$, edge weights $w$
• an initial vertex $u \in V$
• each vertex $v \in V$ has associated adjacency list
• list of $v$’s neighbors
• includes weight of edge from $v$ to each neighbor

Output.

• A map $d: V \to \mathbf{R}$ such that $d[v] = d_w(u, v)$ is the graph distance from $u$ to $v$

• $d[v] = \infty$ indicates no path from $u$ to $v$

## Dijkstra’s Algorithm

1. Initialize $d[u] = 0$ and $d[v] = \infty$ for all $v \neq u$
2. Maintain set $S$ of finalized nodes, initially empty
3. Process nodes. While $S \neq V$ do:
• find node $v$ in $V - S$ with minimal $d[v]$
• add $v$ to $S$
• for each neighbor $x$ of $v$
• update $d[x] \gets \min (d[x], d[v] + w(v, x))$

## Correctness

1. Initialize $d[u] \gets 0$ and $d[v] \gets \infty$ for all $v \neq u$
2. Maintain set $S$ of finalized nodes, initially empty
3. Process nodes: while $S \neq V$
• find node $v$ in $V - S$ with minimal $d[v]$
• add $v$ to $S$
• for each neighbor $x$ of $v$
• update $d[x] \gets \min (d[x], d[v] + w(v, x))$

Claim. For every vertex $v \in S$, $d[v]$ stores the correct (weighted) distance $d_w(u, v)$.

## Proof of Claim

Claim. For every vertex $v \in S$, $d[v]$ stores the correct (weighted) distance $d_w(u, v)$.

Proof. Use induction on size of $S$. Set $k =$ size of $S$.

Base case $k = 1$. Only $u$ is added to $S$. Set $d[u] \gets 0$, which is correct answer.

## Inductive Step I

Inductive hypothesis. When $S$ contains $k$ elements, $d[v]$ is correct for all vertices $v \in S$.

Consider next iteration of outer loop:

• $x$ has $d[x] = \min_{v \in S} (d[v] + w(v, x))$

## Inductive Step II

Must show: $d[x] = d_w(u, x)$; argue by contradiction

1. suppose $d[x] \neq d_w(u, x)$
2. observe: there is a path from $u$ to $x$ of length $d[x]$
3. $\implies d_w(u, x) < d[x]$
4. $\implies$ there is a path $P$ from $u$ to $x$ of length $\ell < d[x]$

## Inductive Step III

Must show: $d[x] = d_w(u, x)$; argue by contradiction

1. suppose $d[x] \neq d_w(u, x)$
2. observe: there is a path from $u$ to $x$ of length $d[x]$
3. $\implies d_w(u, x) < d[x]$
4. $\implies$ there is a path $P$ from $u$ to $x$ of length $\ell < d[x]$
5. $P$ must leave $S$ at some point $y$
6. by definition of $x$, any path from $u$ to $y$ must be longer than $d[x]$
7. $\implies w(P) \geq d[x]$, which contradicts $4$

Conclusion. $d[x] = d_w(u, x)$, as claimed.

## Dijkstra Running Time?

$G$ has $n$ vertices, $m$ edges

Question. How many operations performed?

1. Initialize $d[u] \gets 0$ and $d[v] \gets \infty$ for all $v \neq u$
2. Maintain set $S$ of finalized nodes, initially empty
3. Process nodes: while $S \neq V$
• find node $v$ in $V - S$ with minimal $d[v]$
• add $v$ to $S$
• for each neighbor $x$ of $v$
• update $d[x] \gets \min (d[x], d[v] + w(v, x))$

## For Simplicity

Assume. Vertices are $1, 2, \ldots, n$

• $d$ is an array with $d[v] =$ distance from $u$ to $v$
• $\mathrm{final}$ is a Boolean array with $\mathrm{final}[v] = \mathrm{true}$ if $v$’s distance is finalized
• keep track of number of finalized vertices
• we’re done when $n$ vertices are finalized

## Simple Implementation

For step

• find node $v$ in $V - S$ with minimal $d[v]$

use linear search

Question 1. What is running time of finding min?

Question 2. What is overall running time of Dijkstra?

## Faster Implementation?

Since we need to access $v$ with minimum $d[v]$, store non-finalized vertices in a priority queue

• store elements with associated priorities
• add element with given priority
• remove element with smallest priority

Heap priority queue implementation

• supports these operations with running time $O(\log n)$

For Dijkstra:

• Store un-finalized vertices in priority queue
• priority of $v$ is $d[v]$

## One Sublety, Two Solutions

Issue. Dijkstra decreases priority of vertices

Solution 1. Store duplicate vertices with each new distance

• will still find vertex $v$ with smallest $d[v]$
• if finalized vertex is returned, ignore it
• requires priority queue of size $m$ rather than $n$

Solution 2. Use more sophisticated priority queue that supports “decrease priority” operation

• can be implemented in $O(\log n)$ time

## Conclusion

Dijkstra performs

• $n$ removals of vertices when they are finalized
• $2m$ distance updates

With efficient priority queues, these operations can each be performed in $O(\log n)$ time so…

Result. Dijkstra’s algorithm can be implemented to run in time $O(m \log n)$.

## DPW in Königsberg

Winter is coming to Königsberg!

• Must prepare the bridges for ice
• Each bridge has an associated cost to de-ice
• Königsberg doesn’t have the budget to de-ice all bridges
• For public safety, must ensure that all landmasses are reachable from each other

Question. How to find the cheapest set of bridges to de-ice that maintain connectivity?

## Graph Problem

Input:

• a weighted graph $G = (V, E)$ with edge weights $w$

Output:

• a set $F$ of edges in $E$ such that

1. $(V, F)$ is connected
2. sum of weights of edges in $F$ is minimal among all connected sub-graphs of $G$

The graph $T = (V, F)$ is called a minimum spanning tree of $G$

## Next Time

Greedy algorithms for the minimum spanning tree problem!