Summary


This lecture will be about graphs. A tree is a graph 𝑇=(𝑉,𝐹) which is connected with no cycles.

Note

A graph is a tree if and only if 𝑇 is connected and |𝐹|=|𝑉|βˆ’1.

Definition

A spanning tree of a graph 𝐺=(𝑉,𝐸) is a tree 𝑇=(𝑉,𝐹) with πΉβŠ†πΈ.

A graph can have exponentially many spanning trees; in general, they need not be unique.

Lemma

A graph 𝐺=(𝑉,𝐸) has a spanning tree if and only if 𝐺 is connected.

We can also construct the proof the other way: start with no edges and slowly build up our spanning tree. Both take 𝑂(𝑛2) time. We want to do better.

Minimum Spanning Tree (MST) Problem

Our input is a connected graph 𝐺=(𝑉,𝐸) and edge weights 𝑀:𝐸→ℝ. We output a spanning tree 𝑇=(𝑉,𝐹) of G minimizing

𝑀(𝑇)β‰”βˆ‘π‘’βˆˆπΉπ‘€(𝑒)

Greedy Meta-Algorithm

We have 𝐺=(𝑉,𝐸,𝑀). Initialize 𝐹=βˆ…. While 𝐹 is not a spanning tree, find a safe edge π‘’βˆˆπΈβˆ–πΉ, add 𝑒 to 𝐹, and return 𝐹. The key is how we determine β€œsafe”-ness.

Our key invariant is that 𝐹 is a subset of some MST. Safety means we maintain the invariant.

Theorem

Let πΉβŠ†πΈ be a strict subset of some MST. Let:

  • π‘†βŠ‚π‘‰ be a cut such that no edge of 𝐹 crosses the cut (𝑆,π‘‰βˆ–π‘†)
  • π‘’βˆˆπΈ(𝑆,π‘‰βˆ–π‘†) be a minimum-weight edge crossing the cut.

Then 𝐹βˆͺ{𝑒} is a subset of some MST, i.e. 𝑒 is safe.

The Exchange Property of Spanning Trees

Lemma (Cycle Perspective)

Let 𝐺=(𝑉,𝐸) be a connected graph, 𝑇=(𝑉,𝐹) be a spanning tree of 𝐺, and 𝑒=π‘’π‘£βˆˆπΈβˆ–πΉ. Then:

  • there is a unique path π‘ƒπ‘’βŠ†πΉ connecting 𝑒,𝑣 in 𝑇
  • 𝑃𝑒βˆͺ{𝑒} forms a cycle (called the fundamental cycle of 𝑒 w.r.t. 𝑇)
  • βˆ€π‘’β€²βˆˆπ‘ƒπ‘’, the subgraph 𝑇′=(𝑉,πΉβˆ–{𝑒′}βˆͺ{𝑒}) is a spanning tree.

Lemma (Cut Perspective)

Let 𝐺=(𝑉,𝐸) be a connected graph, 𝑇=(𝑉,𝐹) be a spanning tree of 𝐺, and 𝑒=π‘’π‘£βˆˆπΉ. Then

  • π‘‡βˆ’π‘’ has two components (disconnected)

  • βˆ€π‘’β€²βˆˆπΈ(𝑆,π‘‰βˆ–π‘†), the subgraph 𝑇′=(𝑉,πΉβˆ–{𝑒}βˆͺ{𝑒′}) is a spanning tree.

Kruskal’s Algorithm

We modify our meta-algorithm to be rigorous. Kruskal’s Algorithm grows a bunch of small trees and then merges them together. We will analyze the slower but intuitive version.

The idea is to maintain that 𝐹 is a forest. We get our weighted connected 𝐺 and initialize 𝐹=βˆ…. While βˆƒπ‘’βˆˆπΈβˆ–πΉ such that 𝐹βˆͺ{𝑒} has no cycles, pick such an edge 𝑒 of minimum weight and add 𝑒 to 𝐹.

The fast version uses the observation that 𝐹βˆͺ{𝑒} has no cycles iff 𝑒 connects two distinct connected components. So we need a data structure for fast lookups of whether two vertices are in the same component. We use the union-find data structure. Sort 𝐸 in increasing order of weight (𝑂(π‘šlog𝑛)). For each edge 𝑒=𝑒𝑣 (in sorted order), if 𝑒 and 𝑣 are in different components, add 𝑒 to 𝐹 and union the two components. Each find/union is 𝑂(𝛼(𝑛)) amortized.

The overall runtime is 𝑂(π‘šlog𝑛)+𝑂(π‘šβ‹…π›Ό(𝑛))=𝑂(π‘šlog𝑛).

Prim’s Algorithm

Here, we grow a single tree and absorb isolated vertices at every step. The slow but intuitive version: initialize 𝐹=βˆ…, pick a starting vertex π‘ βˆˆπ‘‰, and set 𝑆={𝑠}. While 𝑆≠𝑉, pick an edge 𝑒=𝑒𝑣 with π‘’βˆˆπ‘†,π‘£βˆˆπ‘‰βˆ–π‘† of minimum weight, add 𝑒 to 𝐹 and 𝑣 to 𝑆. This never introduces cycles since π‘£βˆ‰π‘†.

To make this fast, for each vertex π‘£βˆˆπ‘‰βˆ–π‘† we maintain 𝑑(𝑣)=minπ‘’βˆˆπ‘†π‘€(𝑒,𝑣), the weight of the cheapest edge connecting 𝑣 to the current tree. We need a priority queue supporting:

  • Insert(v, d(v))
  • DeleteMin()
  • DecreaseKey(v, d(v))

Initialize by inserting all vertices with 𝑑(𝑣)=∞ (except 𝑑(𝑠)=0). While the queue is non-empty:

  1. DeleteMin() to extract the closest vertex 𝑒
  2. Add the edge (𝑒,Parent[𝑒]) to 𝐹
  3. For each neighbor 𝑣 of 𝑒 still in the queue, if 𝑀(𝑒,𝑣)<𝑑(𝑣), call DecreaseKey(v, w(u,v)) and set Parent[𝑣]=𝑒

We perform 𝑛 inserts, 𝑛 DeleteMins, and at most π‘š DecreaseKeys. With a binary heap, each operation is 𝑂(log𝑛), giving 𝑂((𝑛+π‘š)log𝑛)=𝑂(π‘šlog𝑛). With a Fibonacci heap, DecreaseKey is 𝑂(1) amortized, improving the total to 𝑂(π‘š+𝑛log𝑛).