@@ -24,7 +24,22 @@ def swap(a: int, b: int) -> tuple[int, int]:
2424
2525def create_sparse (max_node : int , parent : list [list [int ]]) -> list [list [int ]]:
2626 """
27- creating sparse table which saves each nodes 2^i-th parent
27+ Create a sparse table which saves each node's 2^i-th parent.
28+
29+ >>> max_node = 5
30+ >>> parent = [
31+ ... [0, 0, 1, 1, 2, 2], # 2^0-th parents
32+ ... [0, 0, 0, 0, 1, 1] # 2^1-th parents
33+ ... ]
34+ >>> create_sparse(max_node, parent)
35+ [[0, 0, 1, 1, 2, 2], [0, 0, 0, 0, 1, 1]]
36+ >>> max_node = 3
37+ >>> parent = [
38+ ... [0, 0, 1, 1], # 2^0-th parents
39+ ... [0, 0, 0, 0] # 2^1-th parents
40+ ... ]
41+ >>> create_sparse(max_node, parent)
42+ [[0, 0, 1, 1], [0, 0, 0, 0]]
2843 """
2944 j = 1
3045 while (1 << j ) < max_node :
@@ -38,6 +53,46 @@ def create_sparse(max_node: int, parent: list[list[int]]) -> list[list[int]]:
3853def lowest_common_ancestor (
3954 u : int , v : int , level : list [int ], parent : list [list [int ]]
4055) -> int :
56+ """
57+ Return the lowest common ancestor of nodes u and v.
58+
59+ >>> max_node = 13
60+ >>> parent = [[0 for _ in range(max_node + 10)] for _ in range(20)]
61+ >>> level = [-1 for _ in range(max_node + 10)]
62+ >>> graph = {
63+ ... 1: [2, 3, 4],
64+ ... 2: [5],
65+ ... 3: [6, 7],
66+ ... 4: [8],
67+ ... 5: [9, 10],
68+ ... 6: [11],
69+ ... 7: [],
70+ ... 8: [12, 13],
71+ ... 9: [],
72+ ... 10: [],
73+ ... 11: [],
74+ ... 12: [],
75+ ... 13: [],
76+ ... }
77+ >>> level, parent = breadth_first_search(level, parent, max_node, graph, 1)
78+ >>> parent = create_sparse(max_node, parent)
79+ >>> lowest_common_ancestor(1, 3, level, parent)
80+ 1
81+ >>> lowest_common_ancestor(5, 6, level, parent)
82+ 1
83+ >>> lowest_common_ancestor(7, 11, level, parent)
84+ 1
85+ >>> lowest_common_ancestor(6, 7, level, parent)
86+ 3
87+ >>> lowest_common_ancestor(4, 12, level, parent)
88+ 4
89+ >>> lowest_common_ancestor(8, 8, level, parent)
90+ 8
91+ >>> lowest_common_ancestor(9, 10, level, parent)
92+ 5
93+ >>> lowest_common_ancestor(12, 13, level, parent)
94+ 8
95+ """
4196 # u must be deeper in the tree than v
4297 if level [u ] < level [v ]:
4398 u , v = swap (u , v )
@@ -65,9 +120,54 @@ def breadth_first_search(
65120 root : int = 1 ,
66121) -> tuple [list [int ], list [list [int ]]]:
67122 """
68- sets every nodes direct parent
69- parent of root node is set to 0
70- calculates depth of each node from root node
123+ Perform a breadth-first search from the root node of the tree.
124+ Sets every node's direct parent and calculates the depth of each node from the root.
125+
126+ >>> max_node = 5
127+ >>> parent = [[0 for _ in range(max_node + 10)] for _ in range(20)]
128+ >>> level = [-1 for _ in range(max_node + 10)]
129+ >>> graph = {
130+ ... 1: [2, 3],
131+ ... 2: [4],
132+ ... 3: [5],
133+ ... 4: [],
134+ ... 5: []
135+ ... }
136+ >>> level, parent = breadth_first_search(level, parent, max_node, graph, 1)
137+ >>> level[:6]
138+ [ -1, 0, 1, 1, 2, 2]
139+ >>> parent[0][1] == 0
140+ True
141+ >>> parent[0][2] == 1
142+ True
143+ >>> parent[0][3] == 1
144+ True
145+ >>> parent[0][4] == 2
146+ True
147+ >>> parent[0][5] == 3
148+ True
149+
150+ >>> # Test with disconnected graph
151+ >>> max_node = 4
152+ >>> parent = [[0 for _ in range(max_node + 10)] for _ in range(20)]
153+ >>> level = [-1 for _ in range(max_node + 10)]
154+ >>> graph = {
155+ ... 1: [2],
156+ ... 2: [],
157+ ... 3: [4],
158+ ... 4: []
159+ ... }
160+ >>> level, parent = breadth_first_search(level, parent, max_node, graph, 1)
161+ >>> level[:5]
162+ [ -1, 0, 1, -1, -1]
163+ >>> parent[0][1] == 0
164+ True
165+ >>> parent[0][2] == 1
166+ True
167+ >>> parent[0][3] == 0
168+ True
169+ >>> parent[0][4] == 3
170+ True
71171 """
72172 level [root ] = 0
73173 q : Queue [int ] = Queue (maxsize = max_node )
0 commit comments