Skip to content

Commit 7d44fa8

Browse files
committed
Added SCC : Kosaraju, Tarjan
1 parent 50410b9 commit 7d44fa8

File tree

3 files changed

+116
-3
lines changed

3 files changed

+116
-3
lines changed

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313

1414
## Graph
1515

16-
### ETC
17-
1816
### Shotest Path
1917

2018
- [Floyd-Warshall](/graph/shortest_path/floyd_warshall.py)
@@ -24,12 +22,20 @@
2422
- [Bellman-Ford](/graph/shortest_path/bellman_ford.py)
2523
- [BOJ 11657 : 타임머신](https://www.acmicpc.net/problem/11657)
2624

27-
### MST
25+
### MST (Minimum Spanning Tree)
2826

2927
- [Kruskal](/graph/mst/kruskal.py)
3028
- [Prim](/graph/mst/prim.py)
3129
- [BOJ 1197 : 최소 스패닝 트리](https://www.acmicpc.net/problem/1197)
3230

31+
### SCC (Strongly Connected Component)
32+
33+
- [Kosaraju](/graph/scc/kosaraju.py)
34+
- [Tarjan](/graph/scc/tarjan.py)
35+
- [BOJ 2150 : Strongly Connected Component](https://www.acmicpc.net/problem/2150)
36+
37+
### ETC
38+
3339
## String
3440

3541
- [KMP](/string/kmp.py)

graph/scc/kosaraju.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# [BOJ 2150] Strongly Connected Component
2+
# link : https://www.acmicpc.net/problem/2150
3+
# tag : graph, SCC, Kosaraju, DFS, stack
4+
# @subinium
5+
6+
import sys
7+
sys.setrecursionlimit(10000) # 재귀함수 런타임에러 방지
8+
9+
# Kosaraju
10+
def kosaraju(v, edge_raw):
11+
stack, scc = [], [[] for _ in range(v+1)]
12+
visited = [False for _ in range(v+1)]
13+
edge, edge_rev = [[] for _ in range(v+1)], [[] for _ in range(v+1)]
14+
for st, ed in edge_raw:
15+
edge[st].append(ed)
16+
edge_rev[ed].append(st)
17+
18+
# DFS for stack & reverse
19+
def dfs(now, group=0):
20+
visited[now] = True
21+
if group: scc[group].append(now)
22+
for nxt in (edge[now] if group else edge_rev[now]):
23+
if not visited[nxt]: dfs(nxt, group)
24+
if not group: stack.append(now)
25+
26+
for i in range(1, v+1):
27+
if not visited[i]: dfs(i)
28+
29+
num_groups = 0
30+
visited = [False for _ in range(v+1)]
31+
32+
for i in stack[::-1]:
33+
if not visited[i]:
34+
num_groups += 1
35+
dfs(i, num_groups)
36+
37+
return num_groups, scc[1: 1+num_groups]
38+
39+
40+
# Main
41+
if __name__ == '__main__':
42+
input = sys.stdin.readline
43+
V, E = map(int, input().split())
44+
edge = [tuple(map(int, input().split())) for _ in range(E)]
45+
num_groups, scc = kosaraju(V, edge)
46+
for i in range(num_groups):
47+
scc[i].sort()
48+
scc[i].append(-1)
49+
50+
print(num_groups)
51+
for group in sorted(scc):
52+
print(' '.join(map(str, group)))

graph/scc/tarjan.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# [BOJ 2150] Strongly Connected Component
2+
# link : https://www.acmicpc.net/problem/2150
3+
# tag : graph, SCC, Tarjan, DFS, stack
4+
# @subinium
5+
6+
import sys
7+
sys.setrecursionlimit(10000) # 재귀함수 런타임에러 방지
8+
9+
# Tarjan Algorithm
10+
def tarjan(v, edge_raw):
11+
stack, scc, cnt = [], [], [0] # cnt를 내부함수 전역변수로 쓰기 위해
12+
visited, finished = [0 for _ in range(v+1)], [False for _ in range(v+1)]
13+
edge = [[] for _ in range(v+1)]
14+
for st, ed in edge_raw: edge[st].append(ed)
15+
16+
def dfs(now):
17+
cnt[0] += 1
18+
visited[now] = cnt[0]
19+
stack.append(now)
20+
result = visited[now]
21+
22+
for nxt in edge[now]:
23+
if visited[nxt] == 0: result = min(result, dfs(nxt))
24+
elif not finished[nxt]: result = min(result, visited[nxt])
25+
26+
if result == visited[now]:
27+
group = []
28+
while True:
29+
top = stack.pop()
30+
group.append(top)
31+
finished[top] = True
32+
if top == now: break
33+
scc.append(group)
34+
35+
return result
36+
37+
for i in range(1, v+1):
38+
if visited[i] == 0: dfs(i)
39+
40+
return len(scc), scc
41+
42+
43+
# Main
44+
if __name__ == '__main__':
45+
input = sys.stdin.readline
46+
V, E = map(int, input().split())
47+
edge = [tuple(map(int, input().split())) for _ in range(E)]
48+
num_groups, scc = tarjan(V, edge)
49+
for i in range(num_groups):
50+
scc[i].sort()
51+
scc[i].append(-1)
52+
53+
print(num_groups)
54+
for group in sorted(scc):
55+
print(' '.join(map(str, group)))

0 commit comments

Comments
 (0)