Professional Documents
Culture Documents
Graph (II) : David Wai (WJX) 2024-03-09
Graph (II) : David Wai (WJX) 2024-03-09
Graph (II)
David Wai {wjx}
2024-03-09
Graph (II) 2
Reference
This slide is mainly adapted from Graph (II) slides (2021) by Bryan Chung
Graph (II) 3
Prerequisite
Graph I
● Basics Concepts
● Graph Representations
● Grid graph
Data Structure II
● Heap
● DSU
Graph (II) 4
Todayʼs Topics
Shortest Path
● Dijkstra’s Algorithm
● Bellman-Ford Algorithm
● Shortest Path Faster Algorithm (SPFA)
● Floyd-Warshall Algorithm
Graph Modelling Techniques
Minimum Spanning Tree (MST)
● Prim’s Algorithm
● Kruskal’s Algorithm
● Borůvka's algorithm
Graph (II) 5
Codeforces
● CF1633E - Spanning Tree Queries
● CF1776J - Italian Data Centers
● CF1801D - The way home
● CF1898F - Vova Escapes the Matrix
Graph (II) 6
Shortest Path
Graph (II) 7
Shortest Path 2
20
5
8
1 6
1 7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 8
Shortest Path 2
20
5
8
1 6
1 7
5
9 5
3 9
2 Total Cost
5 + 20 = 25
4 6 4
8 3
Graph (II) 9
Shortest Path 2
20
5
8
1 6
1 7
5
9 5
3 9
2 Total Cost
5 + 8 + 5 + 9 = 27
4 6 4
8 3
Graph (II) 10
Shortest Path 2
20
5
8
1 6
1 7
5
9 5
3 9
2 Total Cost
9 + 2 + 1 + 5 + 9 = 26
4 6 4
8 3
Graph (II) 11
Shortest Path 2
20
5
8
1 6
1 7
5
9 5
3 9
2 Total Cost
9 + 6 + 9 = 24
4 6 4
8 3
Graph (II) 12
Shortest Path 2
20
5
8
1 6
1 7
5
9 5
3 9
Shortest Path
2 1→3→4→6
(with cost = 24)
4 6 4
8 3
Graph (II) 13
BFS 2
For unweighted graphs (all edges’ weight = 1),
we can use BFS
1 6
7
5
4
8 3
Graph (II) 14
BFS 2
For unweighted graphs (all edges’ weight = 1),
dist = 0
we can use BFS
1 6
7
5
4
8 3
Graph (II) 15
dist = 1
BFS 2
For unweighted graphs (all edges’ weight = 1),
dist = 0
we can use BFS
1 6
7
5
4
8 3
dist = 1
Graph (II) 16
dist = 1
BFS 2
For unweighted graphs (all edges’ weight = 1),
dist = 0
we can use BFS
1 dist = 2
dist = 2 6
7 dist = 2
5
4
8 3
dist = 2
dist = 1
Graph (II) 17
dist = 1
BFS 2
Why BFS is correct for unweighted graphs?
dist = 0
1 dist = 2
dist = 2 6
● Distance will only increase 7 dist = 2
● Keep choosing the one with minimum
5
distance (as it’s finalized) to spread out
4
8 3
dist = 2
dist = 1
Graph (II) 18
BFS?
What about weighted graphs? 2
Can we just add the costs? 20
5
dist = 0 8
1 6
1 7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 19
BFS? dist = 5
1 6
1 7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 20
BFS? dist = 5
1 dist = 11
dist = 13 6
1 7 dist = 25
5
9 5
3 9
2
4 6 4
8 3
dist = 15
dist = 9
Graph (II) 21
BFS? dist = 5
4 6 4
8 3
dist = 15
Graph (II) 22
BFS?
You can still transform the graph…
But it will cost you a lottttt… 1.4
1.3
O(Cost)
1.2
1.1
1
Graph (II) 23
● Learn to see how greedy algorithms work, and try to apply them in other
tasks
Graph (II) 24
Practice Problems
If you have already implemented shortest path algorithm before / want to
know what kind of question we are going to solve:
Dijkstraʼs Algorithm
Graph (II) 26
Dijkstraʼs Algorithm
It is quite similar to BFS…
REPEAT {
choose an unfinalized node with minimum distance
mark it as finalized
update the neighbours’ distance
} UNTIL (all nodes are finalized)
Graph (II) 27
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 INF INF INF INF INF INF INF
2
final FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
4 6 4
8 3
Graph (II) 28
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 1 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 INF INF INF INF INF INF INF
2
final TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
4 6 4
8 3
Graph (II) 29
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 1 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 INF INF INF INF INF
2
final TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
4 6 4
8 3
Graph (II) 30
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 2 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 INF INF INF INF INF
2
final TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
4 6 4
8 3
Graph (II) 31
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 2 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 INF INF 25 13 INF
2
final TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
4 6 4
8 3
Graph (II) 32
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 3 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 INF INF 25 13 INF
2
final TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE
4 6 4
8 3
Graph (II) 33
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 3 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 15 11 25 13 INF
2
final TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE
4 6 4
8 3
Graph (II) 34
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 5 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 15 11 25 13 INF
2
final TRUE TRUE TRUE FALSE TRUE FALSE FALSE FALSE
4 6 4
8 3
Graph (II) 35
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 5 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 15 11 25 12 INF
2
final TRUE TRUE TRUE FALSE TRUE FALSE FALSE FALSE
4 6 4
8 3
Graph (II) 36
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 7 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 15 11 25 12 INF
2
final TRUE TRUE TRUE FALSE TRUE FALSE TRUE FALSE
4 6 4
8 3
Graph (II) 37
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 7 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 15 11 25 12 INF
2
final TRUE TRUE TRUE FALSE TRUE FALSE TRUE FALSE
4 6 4
// HERE, 12 + 5 > 15, SO NO UPDATE ON dist[4]
8 3
Graph (II) 38
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 4 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 15 11 25 12 INF
2
final TRUE TRUE TRUE TRUE TRUE FALSE TRUE FALSE
4 6 4
8 3
Graph (II) 39
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 4 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 15 11 24 12 INF
2
final TRUE TRUE TRUE TRUE TRUE FALSE TRUE FALSE
4 6 4
// HERE, 15 + 3 > 11, SO NO UPDATE ON dist[5]
8 3
Graph (II) 40
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 6 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 15 11 24 12 INF
2
final TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
4 6 4
8 3
Graph (II) 41
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 6 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 15 11 24 12 INF
2
final TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
4 6 4
// NO NEIGHBOURS FOR NODE 6 :(
8 3
Graph (II) 42
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 8 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 15 11 24 12 INF
2
final TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
4 6 4
8 3
Graph (II) 43
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
// NODE 8 IS CHOSEN 5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 15 11 24 12 INF
2
final TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
4 6 4
// HERE, INF + 4 > 9, SO NO UPDATE ON dist[3]
8 3
Graph (II) 44
Dijkstraʼs Algorithm
2
REPEAT { 20
choose an unfinalized node with minimum distance
5
mark it as finalized
8
update the neighbours’ distance
1 6
} UNTIL (all nodes are finalized)
1
7
5
1 2 3 4 5 6 7 8 9 5
3 9
dist 0 5 9 15 11 24 12 INF
2
final TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
4 6 4
8 3
Graph (II) 45
3 4
6
Graph (II) 57
3 4
6
Graph (II) 58
3 4
6
Graph (II) 59
3 4
6
Graph (II) 60
3 4
6
15 + (-10) = 5 < 11?
Graph (II) 61
3 4
6
Graph (II) 62
3 4
6
Graph (II) 63
3 4
6
30 + (-20) = 10 < 24?
Graph (II) 64
3 4
6
Graph (II) 66
Bellman-Ford Algorithm
Graph (II) 67
Bellman-Ford Algorithm
For a graph without negative cycles…
● A shortest path should not revisits any nodes
● A shortest path should contains no more than V - 1 edges
Bellman-Ford Algorithm
// INITIALIZATION 1 6
1
7
5
9 5
3 9
1 2 3 4 5 6 7 8 2
dist 0 INF INF INF INF INF INF INF
4 6 4
8 3
Graph (II) 69
Bellman-Ford Algorithm
// 1-st ITERATION 1 6
1
7
dist[8] + 4 v.s. dist[3] 5
INF + 4 v.s. INF 9 5
3 9
1 2 3 4 5 6 7 8 2
dist 0 INF INF INF INF INF INF INF
4 6 4
8 3
Graph (II) 70
Bellman-Ford Algorithm
// 1-st ITERATION 1 6
1
7
dist[1] + 9 v.s. dist[3] 5
0 + 9 v.s. INF 9 5
3 9
1 2 3 4 5 6 7 8 2
dist 0 INF 9 INF INF INF INF INF
4 6 4
8 3
Graph (II) 71
Bellman-Ford Algorithm
// 1-st ITERATION 1 6
1
7
dist[1] + 5 v.s. dist[2] 5
0 + 5 v.s. INF 9 5
3 9
1 2 3 4 5 6 7 8 2
dist 0 5 9 INF INF INF INF INF
4 6 4
8 3
Graph (II) 72
Bellman-Ford Algorithm
// 1-st ITERATION 1 6
1
7
dist[4] + 9 v.s. dist[6] 5
INF + 9 v.s. INF 9 5
3 9
1 2 3 4 5 6 7 8 2
dist 0 5 9 INF INF INF INF INF
4 6 4
8 3
Graph (II) 73
// 1-st ITERATION 1 6
1
7
dist[7] + 5 v.s. dist[4] 5
INF + 5 v.s. INF 9 5
3 9
1 2 3 4 5 6 7 8 2
dist 0 5 9 INF INF INF INF INF
4 6 4
8 3
Graph (II) 74
Bellman-Ford Algorithm
// 1-st ITERATION 1 6
1
7
dist[3] + 6 v.s. dist[4] 5
9 + 6 v.s. INF 9 5
3 9
1 2 3 4 5 6 7 8 2
dist 0 5 9 15 INF INF INF INF
4 6 4
8 3
Graph (II) 75
Graph (II) 76
Bellman-Ford Algorithm
// AFTER 7 ITERATIONS 1 6
1
7
5
9 5
3 9
1 2 3 4 5 6 7 8 2
dist 0 5 9 15 11 24 12 INF
4 6 4
8 3
Graph (II) 77
Time Complexity?
O(V×E)
Graph (II) 79
Negative Cycles
s
How to detect negative cycles? 6 -9
SPFA
Improvement of Bellman-Ford Algorithm
by using the data structure: queue
SPFA
Improvement of Bellman-Ford Algorithm
by using the data structure: queue
SPFA - Implementation
Push node 1 into the queue Q
While (Q is not empty)
node u = Q.dequeue
For each edge e from u
If (dist[e.to] > dist[u] + e.cost)
dist[e.to] = dist[u] + e.cost
If (node e.to is not in Q)
Push node e.to into Q
Graph (II) 84
SPFA - Implementation
Push node 1 into the queue Q
While (Q is not empty)
node u = Q.dequeue
For each edge e from u
If (dist[e.to] > dist[u] + e.cost)
dist[e.to] = dist[u] + e.cost
If (node e.to is not in Q)
Push node e.to into Q
SPFA - Implementation
Push node 1 into the queue Q
While (Q is not empty)
node u = Q.dequeue
For each edge e from u
If (dist[e.to] > dist[u] + e.cost)
dist[e.to] = dist[u] + e.cost
If (node e.to is not in Q)
Push node e.to into Q
SPFA - Implementation
inq[1] = TRUE
Push node 1 into the queue Q
While (Q is not empty) inq[u] = FALSE
node u = Q.dequeue
For each edge e from u
If (dist[e.to] > dist[u] + e.cost)
dist[e.to] = dist[u] + e.cost IF NOT inq[e.to]
If (node e.to is not in Q)
Push node e.to into Q inq[e.to] = TRUE
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 1 2
1 2 3 4 5 6 7 8
6 4
dist 0 INF INF INF INF INF INF INF
3
inq TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
4
8
Graph (II) 88
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 2
1 2 3 4 5 6 7 8
6 4
dist 0 INF INF INF INF INF INF INF
3
inq FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
4
8
Graph (II) 89
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 2
1 2 3 4 5 6 7 8
6 4
dist 0 INF INF INF INF INF INF INF
3
inq FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
4
8
Graph (II) 90
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 2
1 2 3 4 5 6 7 8
6 4
dist 0 5 INF INF INF INF INF INF
3
inq FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
4
8
Graph (II) 91
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 2
1 2 3 4 5 6 7 8
6 4
dist 0 5 INF INF INF INF INF INF
3
inq FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
4
8
Graph (II) 92
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 2 2
1 2 3 4 5 6 7 8
6 4
dist 0 5 INF INF INF INF INF INF
3
inq FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
4
8
Graph (II) 93
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 2 2
1 2 3 4 5 6 7 8
6 4
dist 0 5 INF INF INF INF INF INF
3
inq FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
4
8
Graph (II) 94
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 2 2
1 2 3 4 5 6 7 8
6 4
dist 0 5 9 INF INF INF INF INF
3
inq FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
4
8
Graph (II) 95
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 2 2
1 2 3 4 5 6 7 8
6 4
dist 0 5 9 INF INF INF INF INF
3
inq FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
4
8
Graph (II) 96
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 2 3 2
1 2 3 4 5 6 7 8
6 4
dist 0 5 9 INF INF INF INF INF
3
inq FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE
4
8
Graph (II) 97
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 3 2
1 2 3 4 5 6 7 8
6 4
dist 0 5 9 INF INF INF INF INF
3
inq FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE
4
8
Graph (II) 98
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 3 6 7 2
1 2 3 4 5 6 7 8
6 4
dist 0 5 9 INF INF 20 8 INF
3
inq FALSE FALSE TRUE FALSE FALSE TRUE TRUE FALSE
4
8
Graph (II) 99
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 6 7 2
1 2 3 4 5 6 7 8
6 4
dist 0 5 9 INF INF 20 8 INF
3
inq FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE
4
8
Graph (II) 100
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
front
back 3 9
Q 6 7 4 5 2
1 2 3 4 5 6 7 8
6 4
dist 0 5 9 15 11 20 8 INF
3
inq FALSE FALSE FALSE TRUE TRUE TRUE TRUE FALSE
4
8
Graph (II) 101
Graph (II) 102
SPFA
2
Push node 1 into the queue Q 20
While (Q is not empty)
5
node u = Q.dequeue
8
For each edge e from u
1 6
If (dist[e.to] > dist[u] + e.cost)
1
dist[e.to] = dist[u] + e.cost 7
If (node e.to is not in Q) 5
Push node e.to into Q
9 5
3 9
2
1 2 3 4 5 6 7 8
6 4
dist 0 5 9 15 11 24 12 INF
3
inq FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
4
8
Graph (II) 103
SPFA
REMINDER!!!
Work well on random graphs with empirical average time complexity: O(E)
Worst case time complexity: O(VE) // *grid graph*
Floyd-Warshall Algorithm
Graph (II) 105
Floyd-Warshall Algorithm
All-pairs shortest path algorithm
Based on Dynamic Programming (DP)
Floyd-Warshall Algorithm
All-pairs shortest path algorithm
Based on Dynamic Programming (DP)
For every pair of node (p, q),
Check if it is better to go from node p to node 1, then from node 1 to node q
For every pair of node (p, q),
Check if it is better to go from node p to node 2, then from node 2 to node q
For every pair of node (p, q),
Check if it is better to go from node p to node 3, then from node 3 to node q
…
For every pair of node (p, q),
Check if it is better to go from node p to node V, then from node V to node q
Graph (II) 107
Floyd-Warshall Algorithm
Practice Problems
● M1223 - Lucky Path
● M0423 - Running Course
Graph (II) 113
Multiple Layers
Sometimes a node may have multiple statuses
e.g. odd and even steps
It may be useful to build few layers of the original graph
where each layer represents one of the statuses
then build edges between the new nodes
Graph (II) 115
Multiple Layers
B D
A C b d
a c
Graph (II) 116
Multisource
0 2
When there are multiple sources
It can be easily handled by 0 5
20
0 8
Adding a “Super node”
1 6
1
Connect the “Super node” with 7
0 5
All the sources with 0 cost 9 5
3 9
2
And run the shortest path algorithm
By starting at the “Super node” 4 6 4
8 3
Graph (II) 117
MST
2
20
5
8
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
The spanning tree with
total cost of 26
Graph (II) 119
MST
2
20
5
8
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
The spanning tree with
minimum total cost of 24
Graph (II) 120
MST
Spanning Tree
a connected subgraph that is a tree which includes all vertices (nodes)
Minimum Spanning Tree
the spanning tree with minimum possible total weight
Primʼs Algorithm
Graph (II) 122
Primʼs Algorithm
A greedy algorithm…
Primʼs Algorithm
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 124
Primʼs Algorithm
1 6
1
// START WITH NODE 8
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 125
Primʼs Algorithm
1 6
1
// CONNECT TO NODE 3
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 126
Primʼs Algorithm
1 6
1
// CONNECT TO NODE 5
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 127
Primʼs Algorithm
1 6
1
// CONNECT TO NODE 7
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 128
Primʼs Algorithm
1 6
1
// CONNECT TO NODE 4
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 129
Primʼs Algorithm
1 6
1
// CONNECT TO NODE 2
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 130
Primʼs Algorithm
1 6
1
// CONNECT TO NODE 1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 131
Primʼs Algorithm
1 6
1
// CONNECT TO NODE 6
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 132
Primʼs Algorithm
1 6
1
// ALL NODES ARE CONNECTED
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 133
Primʼs Algorithm
Implementation is quite similar to Dijkstra’s Algorithm
You can use a heap to maintain edges
Kruskalʼs Algorithm
Graph (II) 135
Kruskalʼs Algorithm
Sort the edges by their costs (from low to high)
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v
Graph (II) 136
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 137
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (5,7) WITH COST = 1
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 138
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (5,7) WITH COST = 1
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 139
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (5,3) WITH COST = 2
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 140
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (5,3) WITH COST = 2
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 141
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (5,4) WITH COST = 3
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 142
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (5,4) WITH COST = 3
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 143
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (8,3) WITH COST = 4
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 144
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (8,3) WITH COST = 4
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 145
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (7,4) WITH COST = 5
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 146
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (7,4) WITH COST = 5
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 147
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (1,2) WITH COST = 5
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 148
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (1,2) WITH COST = 5
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 149
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (3,4) WITH COST = 6
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 150
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (3,4) WITH COST = 6
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 151
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (2,7) WITH COST = 8
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 152
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (2,7) WITH COST = 8
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 153
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (4,6) WITH COST = 9
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 154
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (4,6) WITH COST = 9
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 155
Kruskalʼs Algorithm
Select edge e = (u, v), from the minimum one to the maximum one
If node u and node v are in different connected component
Use this edge to connect node u and node v 2
20
5
8
// SELECT THE EDGE (1,3) WITH COST = 9
// SELECT THE EDGE (2,6) WITH COST = 20
1 6
1
7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 156
Kruskalʼs Algorithm
You can of course, for each iteration, run an additional DFS or BFS
to check if two nodes are in the same connected component
This has time complexity of O(V+E) per DFS/BFS and has O(E) DFS/BFS,
so overall time complexity is O(E2)
With disjoint set union-find,
you can check connected components in O(α(V)),
so overall time complexity is O(ElogE + Eα(V))
Graph (II) 157
Borůvka's Algorithm
Graph (II) 158
Borůvka's algorithm
For each component, find the minimum edge from it to a different
component
Add all the minimum edges to the MST and connect the components
Repeat until no edges could be added
Graph (II) 159
Borůvka's algorithm
For each component, find the 2
minimum edge from it to a different 20
5
component 8
Add all the minimum edges to the MST 1 6
1
and connect the components 7
5
Repeat until no edges could be added 9 5 9
3
2
4 6 4
8 3
Graph (II) 160
Borůvka's algorithm
For each component, find the 2
minimum edge from it to a different 20
5
component 8
Add all the minimum edges to the MST 1 6
1
and connect the components 7
5
Repeat until no edges could be added 9 5 9
3
2
4 6 4
8 3
Graph (II) 161
Borůvka's algorithm
Time complexity for each iteration: 2
O(E) 20
5
8
Each iteration cuts the number of
components at least half 1 6
1
Overall time complexity: O(ElogV) 7
5
9 5
3 9
2
4 6 4
8 3
Graph (II) 162
MST - Application
Retrieved from HKOJ M1824
Which office should be upgraded?
- Exhaustion
- Dynamic Programming
MST - Application
Retrieved from HKOJ M1824
Connect all offices by
● i) Upgrade the office to "premium office"
all pairs of "premium office" will be connected
● ii) Build cable between offices
Find the minimum cost to make all offices connected
Graph (II) 164
MST - Application
Retrieved from HKOJ M1824
Will simply running MST algorithm work?
No!!!
i) The graph may not be connected
ii) Upgrading some offices to “Premium office” may
Result in lower cost
5
2
1
4
6 3
Graph (II) 165
MST - Application
Retrieved from HKOJ M1824
Adding a “Super node” to represent 0
the connections between “Premium office”
CF1633E 0
3
● N <= 50 vertices and M <= 300 1 9
edges 4 3
● K <= 107 queries consisting of a 8 5
4
single integer x
4
● Cost of a spanning tree = sum of
8
|wi - x| where wi are the weight of 4 2
edges in spanning tree
● Answer to a query = lowest cost of
a spanning tree
Graph (II) 167
CF1633E
Consider the process where we see compare two edges A & B in mst:
0
There is a value y where such that 3
We will use edge A when x <= y, 1 9
4 3
And use edge B when x > y. 8 5
4
4
And y is left for you to think :D
8
(Preprocessing + 2 pointers) !!! 4 2
Graph (II) 168
0 0
3 3
1 9 1 9
4 3 4 3
8 5 8 5
4 4
4
4
8 8
4 2 4 2
Graph (II) 169
0
Build mst first!! 3
Then, for each edge A that is not in the mst,
1 9
4 3
look for the maximum weighted edge in the 8 5
4
Mst which is not equal to edge A
4
8
Efficient sol using LCA!!! (Graph III) :D 4 2
Graph (II) 170
Practice Problems
HKOI Online Judge
● 01041 - Shortest Path (Implementation)
● M1223 - Lucky Path (Shortest Path)
● M1622 - Hyper Knight (Graph Modelling)
● M0423 - Running Course (Cycle Finding)