[파이썬] 백준 2150 : Strongly Connected Component (플레5)
풀이
방향성 생각
- 타잔 알고리즘. 그래프의 사이클 탐색하기
전체코드
import sys
sys.setrecursionlimit(10**6)
input = lambda : sys.stdin.readline().rstrip()
N,M = map(int,input().split())
G = [[] for _ in range(N+1)]
for _ in range(M):
a,b = map(int,input().split())
G[a].append(b)
cnt = 0
V = [-1]*(N+1)
P = [-1]*(N+1)
on_stack = [False]*(N+1)
stack = []
SCC = []
def dfs(x):
global cnt
# 1. 방문 체크 / 카운터 관리 / 스택 관리
V[x] = cnt
P[x] = cnt
cnt += 1
stack.append(x)
on_stack[x] = True
# 2. 스택 관리
for nx in G[x]:
if V[nx] == -1: # 미방문 노드
dfs(nx)
P[x] = min(P[x],P[nx])
elif on_stack[nx]: # SCC에 할당되지 않은 노드에 최소 번호 부여하기 (스택에 없으면 이미 scc에 할당)
P[x] = min(P[x],V[nx])
# 위상정렬 + SCC 진행 / 위상정렬이 필요 없으면 P 배열만 순회하며 된다.
if V[x] == P[x]:
temp = []
while True:
w = stack.pop()
on_stack[w] = False
temp.append(w)
if w == x:
break
SCC.append(temp)
# 타잔알고리즘 실행
for x in range(1,N):
if V[x] == -1:
dfs(x)
# 결과 출력
SCC.sort(key= lambda scc : min(scc))
print(len(SCC))
for scc in SCC:
print(*sorted(scc), -1)
코멘트
- 위상정렬 공부하면서 타잔 알고리즘 공부한 김에 풀이.
- 타잔 알고리즘을 사용하면, 위상정렬의 역순으로 SCC를 얻을 수 있다.
- 그리고 global로 보통 처리를 했는데 레퍼런스 타입인 리스트로 [int] 이렇게 숫자 하나만 넣고 global이나 nonlocal없이 재귀호출된 값을 사용할 수 있다.
- 전체적인 순서 타잔 알고리즘 순서
- dfs를 진행하면 방문체크 (V랑 P에) + 카운터 관리 + 스택관리
- 탐색 진행 : 미방문 노드 / SCC 미할당 노드 관리
- 위상정렬 + SCC 추출
'Algorithm > Graph' 카테고리의 다른 글
[파이썬] SWEA 1247 : 최적 경로 (D5) (0) | 2025.03.09 |
---|---|
[파이썬, 자바] 백준 1506 : 경찰서 (플레5) (0) | 2025.03.09 |
[파이썬, 자바] 백준 4196 : 도미노 (플레4) (0) | 2025.03.08 |
[파이썬] 백준 16475 : 수학 미로 (골드1) (0) | 2025.03.07 |
[파이썬] 백준 22956 : 소나기 (골드1) (0) | 2025.03.06 |
[파이썬] 백준 30894 : 유령의 집 탈출하기 (골드1) (0) | 2025.03.03 |
[파이썬] 백준 18128 : 치삼이의 징검다리 건너기 (골드1) (0) | 2025.03.03 |
댓글