-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathscc.py
More file actions
64 lines (61 loc) · 1.82 KB
/
Copy pathscc.py
File metadata and controls
64 lines (61 loc) · 1.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
def scc(N, edges):
M = len(edges)
start = [0] * (N + 1)
elist = [0] * M
for e in edges:
start[e[0] + 1] += 1
for i in range(1, N + 1):
start[i] += start[i - 1]
counter = start[:]
for e in edges:
elist[counter[e[0]]] = e[1]
counter[e[0]] += 1
low = [0] * N
Ord = [-1] * N
ids = [0] * N
visited = []
now_ord = 0
group_num = 0
for root in range(N):
if Ord[root] != -1:
continue
node_stack = [root]
it_stack = [start[root + 1] - 1]
low[root] = Ord[root] = now_ord
now_ord += 1
visited.append(root)
while node_stack:
v = node_stack[-1]
i = it_stack[-1]
if i >= start[v]:
it_stack[-1] = i - 1
to = elist[i]
if Ord[to] == -1:
low[to] = Ord[to] = now_ord
now_ord += 1
visited.append(to)
node_stack.append(to)
it_stack.append(start[to + 1] - 1)
elif Ord[to] < low[v]:
low[v] = Ord[to]
else:
node_stack.pop()
it_stack.pop()
if low[v] == Ord[v]:
while True:
u = visited.pop()
Ord[u] = N
ids[u] = group_num
if u == v:
break
group_num += 1
if node_stack:
bef = node_stack[-1]
if low[v] < low[bef]:
low[bef] = low[v]
for i in range(N):
ids[i] = group_num - 1 - ids[i]
groups = [[] for _ in range(group_num)]
for i in range(N):
groups[ids[i]].append(i)
return groups