Graphs
Minimum Spanning Trees
Detecting cycles
• Undirected graph
• BFS or DFS.
• If we reach a node we’ve seen already, then we’ve found a
cycle
• Directed graph
• Call TopologicalSort
• If the length of the list returned ≠ |V| then a cycle exists
Problem: Laying Telephone Wire
Central office
Wiring: Naïve Approach
Central office
Expensive!
Wiring: Better Approach
Central office
Minimize the total length of wire connecting the customers
A Networking Problem
Problem: The vertices represent 8 regional data centers which need to
be connected with high-speed data lines. Feasibility studies show that the
links illustrated above are possible, and the cost in millions of dollars is
shown next to the link. Which links should be constructed to enable full
communication and keep the total cost minimal.
Finding spanning trees
• There are two basic algorithms for finding minimum-cost
spanning trees, and both are greedy algorithms
• Prim’s algorithm: Start with any one node in the spanning tree,
and repeatedly add the cheapest edge, and the node it leads to,
for which the node is not already in the spanning tree.
• Here, we consider the spanning tree to consist of both nodes and edges
• Kruskal’s algorithm: Start with no nodes or edges in the
spanning tree, and repeatedly add the cheapest edge that does
not create a cycle
• Here, we consider the spanning tree to consist of edges only
7
Links Will Form a Spanning Tree
Cost (T) = 47 + 23 + 75 + 74 + 55 + 74 + 79
= 427
Minimum Weight Spanning Trees
Problem: Given a connected graph with non-negative
weights on the edges, find a spanning tree T for which
the sum of the weights on the edges in T is as small
as possible.
Why Not Try All Possibilities?
• Suppose the graph has n vertices. Then the number of possible
spanning trees can be as large as n n-2.
• When n = 75, this means that the number of spanning trees can be as
large as
7576562804644601479086318651590413464814067\
83308840339247043281018024279971356804708193\
5219466686248779296875
Minimum Spanning Tree (MST)
A minimum spanning tree is a subgraph of an undirected weighted
graph G, such that
it is a tree (i.e., it is acyclic)
it covers all the vertices V
contains |V| - 1 edges
the total cost associated with tree edges is the
minimum among all possible spanning trees
not necessarily unique
How Can We Generate a MST?
9 b 9 b
a 2 6 a 2 6
d d
4 5 4 5
5 4 5 4
5 e 5 e
c c
Prim’s Algorithm
Prim’s algorithm is a “greedy” algorithm
Greedy algorithms find solutions based on a sequence of choices which are “locally” optimal at each step.
Initialization
a. Pick a vertex r to be the root
b. Set D(r) = 0, parent(r) = null
c. For all vertices v V, v r, set D(v) =
d. Insert all vertices into priority queue P,
using distances as the keys
9 Vertex Parent
b
e -
a 2 6 e a b c d
d
4 5 0
5 4
5 e
c
Prim’s Algorithm
While P is not empty: //P is priority queue
1. Select the next vertex u to add to the tree
u = P.deleteMin()
2. Update the weight of each vertex w adjacent to
u which is not in the tree (i.e., w P)
If weight(u,w) < D(w),
a. parent(w) = u
b. D(w) = weight(u,w)
c. Update the priority queue to reflect
new distance for w
Prim’s algorithm Vertex Parent
e -
e d b c a b -
0 c -
9 d -
b
a 2 6
d Vertex Parent
4 5
5 4 e -
5 e d b c a b e
c 4 5 5 c e
d e
The MST initially consists of the vertex e, and we update
While P is not empty: //P is priority queue
the distances and parent for its adjacent vertices
1. Select the next vertex u to add to the tree
u = P.deleteMin()
2. Update the weight of each vertex w adjacent to
u which is not in the tree (i.e., w P)
If weight(u,w) < D(w),
a. parent(w) = u
b. D(w) = weight(u,w)
c. Update the priority queue to reflect
new distance for w
Prim’s algorithm
Vertex Parent
9 e -
b
a 2 6 d b c a b e
d 4 5 5 c e
4 5 d e
5 4
5 e
c
Vertex Parent
e -
While P is not empty: //P is priority queue
a c b b e
1. Select the next vertex u to add to the tree
2 4 5 c d
u = P.deleteMin()
d e
2. Update the weight of each vertex w adjacent to a d
u which is not in the tree (i.e., w P)
If weight(u,w) < D(w),
a. parent(w) = u d is deleted , and we update
b. D(w) = weight(u,w) the distances and parent for its adjacent vertices
c. Update the priority queue to reflect
new distance for w (updated nodes gets new parent !)
Prim’s algorithm
9
b Vertex Parent
a 2 6 e -
d a c b b e
4 5 c d
5 4 2 4 5
d e
5 e a d
c
While P is not empty: //P is priority queue Vertex Parent
1. Select the next vertex u to add to the tree e -
u = P.deleteMin() c b b e
2. Update the weight of each vertex w adjacent to 4 5 c d
u which is not in the tree (i.e., w P) d e
If weight(u,w) < D(w),
a. parent(w) = u
a d
b. D(w) = weight(u,w)
c. Update the priority queue to reflect
new distance for w
Prim’s algorithm
9
b Vertex Parent
a 6 e -
2
d c b b e
4 5 c d
5 4 4 5
d e
5 e a d
c
While P is not empty: //P is priority queue
Vertex Parent
e -
1. Select the next vertex u to add to the tree b b e
u = P.deleteMin()
5 c d
2. Update the weight of each vertex w adjacent to d e
u which is not in the tree (i.e., w P)
If weight(u,w) < D(w), a d
a. parent(w) = u
b. D(w) = weight(u,w)
c. Update the priority queue to reflect
new distance for w
Prim’s algorithm
Vertex Parent
e -
b b e
5 c d
9
b d e
a 2 6 a d
d
4 5
5 4
5 e
c Vertex Parent
e -
b e
The final minimum spanning tree c d
d e
a d
Running time of Prim’s algorithm (without heaps)
Initialization of priority queue (array): O(|V|)
Update loop: |V| calls
• Choosing vertex with minimum cost edge: O(|V|)
• Updating distance values of unconnected
vertices: each edge is considered only once
during entire execution, for a total of O(|E|)
updates
Overall cost without heaps: O(|E| + |V| )
2)
•What is the run time complexity if heaps are used?
Kruskal’s Algorithm (Avoid Cycles)
• Sort the edges by weight
• Build a spanning forest (that eventually becomes a
tree) by adding the edge of minimum weight which
when added to those already chosen does not form
a cycle.
Kruskal’s algorithm
T = empty spanning tree;
E = set of edges;
N = number of nodes in graph;
while T has fewer than N - 1 edges {
remove an edge (v, w) of lowest cost from E
if adding (v, w) to T would create a cycle
then discard (v, w)
else add (v, w) to T
}
• Finding an edge of lowest cost can be done just by sorting
the edges
• Testing for a cycle: Efficient testing for a cycle requires a
additional algorithm (UNION-FIND) which we don’t cover in
this course. The main idea: If both nodes v, w are in the
same component of T, then adding (v, w) to T would result
in a cycle.
Kruskal – Step 1
• Sort the edges by weight
• Build a spanning forest (that eventually becomes a tree) by adding the edge of minimum weight which
when added to those already chosen does not form a cycle.
Kruskal – Step 2
• Sort the edges by weight
• Build a spanning forest (that eventually becomes a tree) by adding the edge of minimum weight which
when added to those already chosen does not form a cycle.
Kruskal – Step 3
• Sort the edges by weight
• Build a spanning forest (that eventually becomes a tree) by adding the edge of minimum weight which
when added to those already chosen does not form a cycle.
Kruskal – Step 4
• Sort the edges by weight
• Build a spanning forest (that eventually becomes a tree) by adding the edge of minimum weight which
when added to those already chosen does not form a cycle.
Kruskal – Step 5
• Sort the edges by weight
• Build a spanning forest (that eventually becomes a tree) by adding the edge of minimum weight which
when added to those already chosen does not form a cycle.
Kruskal – Step 6
• Sort the edges by weight
• Build a spanning forest (that eventually becomes a tree) by adding the edge of minimum weight which
when added to those already chosen does not form a cycle.
Why Avoiding Cycles Matters
Up to this point, we have simply taken the
edges in order of their weight. But now we
will have to reject an edge since it forms a
cycle when added to those already chosen.
Forms a Cycle
So we cannot take the blue edge having weight 55.
• Sort the edges by weight
• Build a spanning forest (that eventually becomes a tree) by adding the edge of minimum weight which
when added to those already chosen does not form a cycle.
Kruskal – Step 7 DONE!!
Weight (T) = 23 + 29 + 31 + 32 + 47 + 54 + 66 = 282
Kruskal
Example 2704
BOS
867
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
32
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
34
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
35
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
36
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
37
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
38
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
39
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
40
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
41
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
42
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
43
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
44
Example 2704
867 BOS
849 PVD
ORD 187
740 144
1846 621 JFK
184 1258
802
SFO BWI
1391
1464
337 1090
DFW 946
LAX 1235
1121
MIA
2342
45
Data Structures
for Kruskal’s Algorithm
|E| times:
Pick the lowest cost edge…
findMin/deleteMin
|E| times:
Data structures?
If u and v are not already connected…
…connect u and v. Runtime?
find representative
union