1
1
from collections import deque
2
2
3
3
4
- def tarjan (g ) :
4
+ def tarjan (g : list [ list [ int ]]) -> list [ list [ int ]] :
5
5
"""
6
6
Tarjan's algo for finding strongly connected components in a directed graph
7
7
@@ -19,15 +19,30 @@ def tarjan(g):
19
19
Complexity: strong_connect() is called at most once for each node and has a
20
20
complexity of O(|E|) as it is DFS.
21
21
Therefore this has complexity O(|V| + |E|) for a graph G = (V, E)
22
+
23
+ >>> tarjan([[2, 3, 4], [2, 3, 4], [0, 1, 3], [0, 1, 2], [1]])
24
+ [[4, 3, 1, 2, 0]]
25
+ >>> tarjan([[], [], [], []])
26
+ [[0], [1], [2], [3]]
27
+ >>> a = [0, 1, 2, 3, 4, 5, 4]
28
+ >>> b = [1, 0, 3, 2, 5, 4, 0]
29
+ >>> n = 7
30
+ >>> sorted(tarjan(create_graph(n, list(zip(a, b))))) == sorted(
31
+ ... tarjan(create_graph(n, list(zip(a[::-1], b[::-1])))))
32
+ True
33
+ >>> a = [0, 1, 2, 3, 4, 5, 6]
34
+ >>> b = [0, 1, 2, 3, 4, 5, 6]
35
+ >>> sorted(tarjan(create_graph(n, list(zip(a, b)))))
36
+ [[0], [1], [2], [3], [4], [5], [6]]
22
37
"""
23
38
24
39
n = len (g )
25
- stack = deque ()
40
+ stack : deque [ int ] = deque ()
26
41
on_stack = [False for _ in range (n )]
27
42
index_of = [- 1 for _ in range (n )]
28
43
lowlink_of = index_of [:]
29
44
30
- def strong_connect (v , index , components ) :
45
+ def strong_connect (v : int , index : int , components : list [ list [ int ]]) -> int :
31
46
index_of [v ] = index # the number when this node is seen
32
47
lowlink_of [v ] = index # lowest rank node reachable from here
33
48
index += 1
@@ -57,16 +72,24 @@ def strong_connect(v, index, components):
57
72
components .append (component )
58
73
return index
59
74
60
- components = []
75
+ components : list [ list [ int ]] = []
61
76
for v in range (n ):
62
77
if index_of [v ] == - 1 :
63
78
strong_connect (v , 0 , components )
64
79
65
80
return components
66
81
67
82
68
- def create_graph (n , edges ):
69
- g = [[] for _ in range (n )]
83
+ def create_graph (n : int , edges : list [tuple [int , int ]]) -> list [list [int ]]:
84
+ """
85
+ >>> n = 7
86
+ >>> source = [0, 0, 1, 2, 3, 3, 4, 4, 6]
87
+ >>> target = [1, 3, 2, 0, 1, 4, 5, 6, 5]
88
+ >>> edges = list(zip(source, target))
89
+ >>> create_graph(n, edges)
90
+ [[1, 3], [2], [0], [1, 4], [5, 6], [], [5]]
91
+ """
92
+ g : list [list [int ]] = [[] for _ in range (n )]
70
93
for u , v in edges :
71
94
g [u ].append (v )
72
95
return g
0 commit comments