14.14 Graph Greedy
Many of the most successful graph algorithms are greedy algorithms.
14.14 Graph Greedy
Many of the most successful graph algorithms are greedy algorithms. At first glance, this may seem surprising. Graphs contain complex global structure. A local decision on one edge can affect paths, connectivity, cycles, and costs throughout the entire graph.
Yet some graph problems possess exactly the structural properties that greedy algorithms require. In these cases, local choices can be proven safe through cut properties, exchange arguments, or matroid theory. The resulting algorithms are among the most efficient in computer science.
This recipe introduces the graph greedy pattern and develops the ideas that unify algorithms such as Kruskal's minimum spanning tree algorithm, Prim's algorithm, and Dijkstra's shortest path algorithm.
Problem
Given a graph:
$$ G = (V,E) $$
find an optimal structure such as:
- A spanning tree
- A shortest path tree
- A connectivity structure
- A minimum-cost network
The challenge is determining whether local edge choices can safely contribute to a globally optimal solution.
Why Graph Greedy Is Different
In interval scheduling, choosing one interval affects only neighboring intervals.
In graph problems, a single edge may affect:
- Connectivity
- Reachability
- Cycles
- Path lengths
- Future edge choices
This makes correctness proofs substantially more challenging.
The key question becomes:
Which graph edges are guaranteed to belong to some optimal solution?
Once such edges can be identified, greedy algorithms become possible.
Example: Minimum Spanning Tree
Given a connected weighted graph:
4
A -------- B
| |
|1 3|
| |
C -------- D
2
Goal:
Connect all vertices while minimizing total edge weight.
A spanning tree contains:
|V| - 1
edges and no cycles.
Naive Search
A graph with:
m
edges contains exponentially many subsets.
Checking all spanning trees quickly becomes impractical.
We need a more direct strategy.
Greedy Observation
Suppose the smallest edge in the graph has weight:
1
Can an optimal spanning tree exclude it?
Often the answer is no.
This observation motivates a greedy rule:
Prefer small edges whenever possible.
The challenge is proving which small edges are safe.
The Cut Property
Consider any partition of vertices:
Left side
Right side
Among all edges crossing the partition, choose the minimum-weight edge.
The cut property states:
That edge belongs to some minimum spanning tree.
This is one of the most important theorems in greedy algorithm design.
It transforms a local statement:
This edge is cheapest across a cut.
into a global statement:
This edge is safe to include.
Kruskal's Algorithm
The simplest MST algorithm follows directly.
Step 1
Sort all edges by weight.
Step 2
Process edges from smallest to largest.
Step 3
Add an edge if it does not create a cycle.
Pseudo-code:
Sort edges by weight
For each edge:
If edge creates no cycle:
Add edge
The algorithm stops after:
|V| - 1
edges have been selected.
Example
Edges:
| Edge | Weight |
|---|---|
| A-C | 1 |
| C-D | 2 |
| B-D | 3 |
| A-B | 4 |
Process:
Take A-C
Take C-D
Take B-D
Now all vertices are connected.
Tree weight:
$$ 1 + 2 + 3 = 6 $$
The final edge:
A-B
would create a cycle and is rejected.
Why Kruskal Works
Suppose Kruskal chooses edge:
e
and an optimal spanning tree does not contain it.
Add:
e
to the tree.
A cycle appears.
Within that cycle exists another edge:
f
whose weight is at least as large.
Replace:
f
with:
e
The resulting tree remains connected.
Total weight does not increase.
Therefore an optimal tree exists containing:
e
This exchange argument proves the greedy choice.
Union-Find
Kruskal requires fast cycle detection.
A disjoint-set structure supports:
Find
Union
operations efficiently.
For each edge:
if Find(u) != Find(v) {
Union(u, v)
}
This determines whether two vertices already belong to the same component.
Complexity
Sorting:
$$ O(E \log E) $$
Union-find operations:
$$ O(E \alpha(V)) $$
Total:
$$ O(E \log E) $$
which is dominated by sorting.
Prim's Algorithm
Prim approaches the same problem differently.
Instead of sorting all edges once, it grows a tree incrementally.
Start with an arbitrary vertex.
Repeatedly:
Add the cheapest edge connecting the current tree to a new vertex.
This again relies on the cut property.
The current tree defines a cut.
The minimum crossing edge is always safe.
Example
Start:
A
Available edges:
A-C (1)
A-B (4)
Choose:
A-C
Now:
A C
Available crossing edges:
C-D (2)
A-B (4)
Choose:
C-D
Continue until all vertices are included.
Priority Queue Implementation
Prim naturally uses a min-heap.
heap.Push(pq, edge)
Each step extracts:
edge := heap.Pop(pq)
with minimum weight.
The algorithm therefore combines:
- Graph traversal
- Greedy selection
- Priority queues
Dijkstra's Algorithm
Dijkstra solves a different problem.
Goal:
Find shortest paths from a source vertex.
The greedy rule is:
Select the unreached vertex with the smallest tentative distance.
At first glance this seems dangerous.
How do we know a shorter path will not appear later?
The answer depends on a critical assumption:
All edge weights are nonnegative.
Under this assumption, distances can only increase as paths grow.
Once the smallest tentative distance is selected, it becomes final.
Example
Distances:
| Vertex | Tentative Distance |
|---|---|
| A | 0 |
| B | 5 |
| C | 8 |
| D | 12 |
The smallest unreached vertex is:
B
Any future path to B must pass through vertices with distance at least 5.
Therefore no shorter path can emerge later.
The greedy choice is safe.
Common Structure
Although Kruskal, Prim, and Dijkstra solve different problems, they share a common pattern.
Maintain Partial Solution
A forest, tree, or distance map.
Identify Safe Choice
Smallest edge or shortest distance.
Prove Safety
Using:
- Cut property
- Exchange argument
- Monotonicity
Commit Permanently
The choice never needs reconsideration.
This permanence is what distinguishes greedy algorithms from dynamic programming.
Recognizing Graph Greedy Problems
Several signals suggest a greedy graph solution.
Local Edge Decisions
Optimality depends on choosing individual edges.
Monotonic Progress
The solution only grows.
Safe Edge Theorems
Some edges can be proven optimal independently.
No Need for Backtracking
Once selected, edges remain selected.
Matroid Structure
The problem resembles spanning tree construction or independent-set selection.
When Graph Greedy Fails
Many graph problems do not possess safe local choices.
Examples:
- Traveling Salesman Problem
- Longest Path Problem
- General Steiner Tree
- Most NP-hard graph optimizations
For these problems, locally attractive edges often lead to globally poor solutions.
The absence of a safe-edge theorem is usually a warning sign.
Comparing Graph Greedy Algorithms
| Algorithm | Goal | Greedy Choice |
|---|---|---|
| Kruskal | MST | Smallest safe edge |
| Prim | MST | Cheapest crossing edge |
| Dijkstra | Shortest paths | Smallest tentative distance |
| Huffman | Coding tree | Smallest frequencies |
| Interval scheduling | Maximum intervals | Earliest finish |
Different domains, same pattern.
Each algorithm repeatedly commits to a locally optimal choice that can be proven globally safe.
Takeaway
Graph greedy algorithms succeed when local graph decisions can be shown to belong to some optimal solution. The key tools are cut properties, exchange arguments, and monotonicity arguments. Kruskal, Prim, and Dijkstra demonstrate three variations of the same strategy: maintain a partial solution, identify a safe local choice, prove its safety, and commit permanently. Understanding these proofs is often more important than memorizing the algorithms themselves, because the proofs reveal when greedy reasoning is valid and when a graph problem requires a fundamentally different approach.