G III
G III
Graph (III)
Ip Tsz Oi {ITO}
2024-04-06
Graph (III) 2
Table of Contents
Rooted Tree
Binary Tree
Tree traversal
Tree diameter
Practice Problems
Graph (III) 3
Prerequisite
● Graph (I)
○ basic concepts, graph representation, grid graph,
○ depth first search, flood fill, breadth first search
● Graph (II)
○ shortest path algorithms for weighted graphs,
○ minimum spanning tree
● Data Structures (III)
○ sparse table, segment tree,
○ lazy propagation, 1-d/2-d binary indexed tree
● Dynamic Programming (I)
○ Knapsack Problems
Graph (III) 5
Overview
Tree:
● Definition and properties
Algorithms on tree:
● Pre-order, in-order and post-order
● Tree diameter
● Lowest common ancestor
● (DAG and topological sort)
Graph (III) 6
Revision: tree
● A tree is a connected graph with no cycles.
● Vertices of a tree are also called nodes.
● A tree can be either weighted or unweighted, and
either rooted or unrooted.
Not a tree →
∵ has cycles
(e.g. {1, 6, 8})
← Tree
Graph (III) 7
Revision: tree
● There are various equivalent definitions of a tree:
○ A connected graph with V vertices and V - 1 edges.
○ A connected graph with no cycles.
○ Between any two vertices on the graph, there is only one simple
(also the shortest) path between them.
● These properties make problems easier to solve.
Graph (III) 8
Rooted Tree
Graph (III) 9
Rooted tree
1
● Sometimes one of the nodes of the tree
will be viewed as the root of the tree
● Then the tree becomes directed 2 3
7 8
9 10
Graph (III) 10
Parent 2 3
Sibling 4 5 6
As seen
from here
7 8
Children
9 10
Graph (III) 11
Ancestors
2 3
4 5 6
As seen
from here
7 8
Descendants
9 10
Graph (III) 12
2 3
4 5 6
As seen
from here
Subtrees 7 8
9 10
Graph (III) 13
2 3
4 5 6
Leaves 7 8
9 10
Graph (III) 14
Depth = 1 2 3
Depth = 2 4 5 6 Height = 4
Depth = 3 7 8
Depth = 4 9 10
Graph (III) 15
Tree: implementation
● Trees are graph so the Node Parent Child[0] Child[1]
same representations
1
1 2 3
are used. 2 1 4 5
3 1 6 2 3
○ e.g. adjacency matrix,
4 2
adjacency list, edge
5 2 7 8 4 5 6
list 6 3
● For rooted tree, we can 7 5 7 8
choose to store the 8 5 9 10
parent and children 9 8
9 10
10 8
separately.
Graph (III) 16
Tree: application
Some graph problems are trivial in trees.
● Shortest path between two nodes → the only path between two nodes
● Minimum spanning tree → the tree itself
Trees are also used in data structures.
● Binary search tree
● Heap
● Trie
● Segment Tree
● Suffix Tree
Graph (III) 17
Binary Tree
Graph (III) 18
Binary Tree
A rooted tree where all vertices (nodes) have at most 2 children.
Graph (III) 19
Tree traversal
Graph (III) 22
Tree traversal
We can perform DFS on trees as we void dfs(int node) {
for (auto child : children[node])
do on graph. dfs(child);
}
2 3
4 5 6
7 8
Graph (III) 23
2 3
Pre-order 1 2 4 5 7 8 3 6
4 5 6
In-order 4 2 7 5 8 1 3 6
7 8 Post-order 4 7 8 5 2 6 3 1
Graph (III) 24
Pre-order
1 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 25
Pre-order
1 2 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 26
Pre-order
1 2 4 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 27
Pre-order
1 2 4 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 28
Pre-order
1 2 4 5 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 29
Pre-order
1 2 4 5 7 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 30
Pre-order
1 2 4 5 7 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 31
Pre-order
1 2 4 5 7 8 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 32
Pre-order
1 2 4 5 7 8 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 33
Pre-order
1 2 4 5 7 8 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 34
Pre-order
1 2 4 5 7 8 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 35
Pre-order
1 2 4 5 7 8 3 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 36
Pre-order
1 2 4 5 7 8 3 6 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 37
Pre-order
1 2 4 5 7 8 3 6 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 38
Pre-order
1 2 4 5 7 8 3 6 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 39
Pre-order
1 2 4 5 7 8 3 6 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 40
Pre-order
1 2 4 5 7 8 3 6 void preorder_traversal(int node) {
process(node);
if (left_child[node])
preorder_traversal(left_child[node]);
1
if (right_child[node])
preorder_traversal(right_child[node]);
}
2 3
In-order
void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 42
In-order
void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 43
In-order
4 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 44
In-order
4 2 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 45
In-order
4 2 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 46
In-order
4 2 7 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 47
In-order
4 2 7 5 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 48
In-order
4 2 7 5 8 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 49
In-order
4 2 7 5 8 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 50
In-order
4 2 7 5 8 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 51
In-order
4 2 7 5 8 1 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 52
In-order
4 2 7 5 8 1 3 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 53
In-order
4 2 7 5 8 1 3 6 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 54
In-order
4 2 7 5 8 1 3 6 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 55
In-order
4 2 7 5 8 1 3 6 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 56
In-order
4 2 7 5 8 1 3 6 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
4 5 6
7 8
Graph (III) 57
In-order
4 2 7 5 8 1 3 6 void inorder_traversal(int node) {
if (left_child[node])
inorder_traversal(left_child[node]);
process(node);
1
if (right_child[node])
inorder_traversal(right_child[node]);
}
2 3
Post-order
void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 59
Post-order
void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 60
Post-order
4 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 61
Post-order
4 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 62
Post-order
4 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 63
Post-order
4 7 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 64
Post-order
4 7 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 65
Post-order
4 7 8 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 66
Post-order
4 7 8 5 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 67
Post-order
4 7 8 5 2 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 68
Post-order
4 7 8 5 2 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 69
Post-order
4 7 8 5 2 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 70
Post-order
4 7 8 5 2 6 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 71
Post-order
4 7 8 5 2 6 3 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 72
Post-order
4 7 8 5 2 6 3 1 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 73
Post-order
4 7 8 5 2 6 3 1 void postorder_traversal(int node) {
if (left_child[node])
postorder_traversal(left_child[node]);
if (right_child[node])
1 postorder_traversal(right_child[node]);
process(node);
}
2 3
4 5 6
7 8
Graph (III) 75
2 3
Pre-order 1 2 4 5 7 8 3 6
4 5 6
In-order 4 2 7 5 8 1 3 6
Post-order 4 7 8 5 2 6 3 1 7 8
Graph (III) 76
Tree diameter
Graph (III) 85
Tree diameter
The diameter of a tree is the furthest distance between
any two nodes in the tree.
For example, in the tree on the right, the diameter of
the tree is 5.
Graph (III) 86
int diameter() {
max_depth = 0;
dfs(1, -1, 0);
max_depth = 0;
dfs(deepest_node, -1, 0);
return max_depth;
}
Graph (III) 89
4 5 6
7 8
Graph (III) 91
Second DFS
4 5 6
Node 1 2 3 4 5 6 7 8
Depth 3 2 4 3 1 5 0 2
7 8
Graph (III) 92
4 5 6
7 8
Graph (III) 93
7 8
Graph (III) 94
1 2 4 4 2 5 7 7 5 8 8 5 2 1 3 6 6 3 1
Graph (III) 98
1 2 4 4 2 5 7 7 5 8 8 5 2 1 3 6 6 3 1
0 1 2 2 1 2 3 3 2 3 3 2 1 0 1 2 2 1 0
Graph (III) 99
1 2 4 4 2 5 7 7 5 8 8 5 2 1 3 6 6 3 1
0 1 2 2 1 2 3 3 2 3 3 2 1 0 1 2 2 1 0
Graph (III) 100
Node 1 2 3 4 5 6 7 8
i=0 1 1 1 2 2 3 5 5
i=1 1 1 1 1 1 1 2 2
i=2 1 1 1 1 1 1 1 1
i=3 1 1 1 1 1 1 1 1
Graph (III) 103
Node 1 2 3 4 5 6 7 8
i=0 1 1 1 2 2 3 5 5
i=1 1 1 1 1 1 1 2 2
i=2 1 1 1 1 1 1 1 1
i=3 1 1 1 1 1 1 1 1
Graph (III) 104
Node 1 2 3 4 5 6 7 8
i=0 1 1 1 2 2 3 5 5
i=1 1 1 1 1 1 1 2 2
i=2 1 1 1 1 1 1 1 1
i=3 1 1 1 1 1 1 1 1
Graph (III) 105
● Time complexity:
2 3
○ Precomputation: O(N log N)
○ Query: O(log N)
6
● Space complexity: O(N log N) 4 5
7 8
Node 1 2 3 4 5 6 7 8
i=0 1 1 1 2 2 3 5 5
i=1 1 1 1 1 1 1 2 2
i=2 1 1 1 1 1 1 1 1
i=3 1 1 1 1 1 1 1 1
Graph (III) 109
4 5 6
7 8
Graph (III) 111
3
4 1
5 2
Graph (III) 114
Topological Sort
● A topological ordering is an order of vertices in a graph where
if there is an edge A → B, then A appears before B.
● For example, in the graph on the right, one of the
6
topological orderings is
[4, 5, 1, 6, 3, 2] 3
4
● A graph has a topological ordering 1
Topological Sort
● To obtain a topological order, vector<pair<int, int>> edge_list;
vector<vector<int>> edges;
we can repeat the process of vector<int> topological_sort() {
int n = edge_list.size();
removing nodes with no for (auto [u, v] : edge_list) in_drgree[v]++;
queue<int> q;
incoming edges and all edges for (int i = 0; i < n; i++)
if (in_drgree[i] == 0) q.push(i);
from that node. vector<int> order;
while (!q.empty()) {
● The code is shown on the right. int u = q.front();
q.pop();
● We will demonstrate with order.push_back(u);
for (auto v : edges[u]) {
samples below. in_drgree[v]--;
if (in_drgree[v] == 0) q.push(v);
}
}
return order;
}
Graph (III) 116
Practice Problems
● HKOJ 01038 - Preorder Tree Traversal
● HKOJ 01039 - Postorder Tree Traversal
● HKOJ S042 - Teacher’s Problem
● HKOJ M0642 - Cells
● HKOJ T114 - Current Flow
● HKOJ T172 - City Reform
● HKOJ I1311 - Dreaming
● Codeforces 191C - Fools and Roads
● Codeforces 208E - Blood Cousins
● AtCoder nikkei2019_qual_d - Restore the Tree
● AtCoder past201912_k - Conglomerate
Graph (III) 131
Reference
https://assets.hkoi.org/training2019/g-iii.pdf
https://assets.hkoi.org/training2021/g-iii.pdf
https://assets.hkoi.org/training2022/g-iii.pdf
https://assets.hkoi.org/training2023/g-iii.pdf
https://codeforces.com/blog/entry/13168