[파이썬, 자바] 백준 4196 : 도미노 (플레4)
풀이
방향성 생각
- 타잔 알고리즘으로 얻은 SCC는 위상정렬의 역순으로 나온다.
- 얻은 SCC에서 각 scc를 하나의 노드로 인식하게 만들어준다.
- 새로운 노드간 그래프를 읽어서 진입차수를 계산해주기.
파이썬
from collections import deque
import sys
sys.setrecursionlimit(10**6)
input = lambda : sys.stdin.readline().strip()
TC = int(input())
for tc in range(TC):
# 타잔
N,M = map(int,input().split())
# 방문, 그룹관리, 카운팅, 스택 관리
V = [-1]*(N+1)
P = [-1]*(N+1)
count = [0]
stack = deque()
on_stack = [False]*(N+1)
# 그래프
G = [[] for _ in range(N+1)]
for _ in range(M):
a,b = map(int,input().split())
G[a].append(b)
# 타잔 알고리즘
SCC = []
def dfs(x):
# 방문처리
V[x] = count[0]
P[x] = count[0]
count[0] += 1
stack.append(x)
on_stack[x] = True
# 탐색
for nx in G[x]:
if V[nx] == -1:
dfs(nx)
P[x] = min(P[x],P[nx])
elif on_stack[nx]:
P[x] = min(P[x],V[nx])
# SCC 추출하기
if V[x] == P[x]:
scc = []
while stack:
w = stack.pop()
on_stack[w] = False
scc.append(w)
if w==x:
break
SCC.append(scc)
# 모든 노드에 대해서 DFS
for i in range(1,N+1):
if V[i] == -1:
dfs(i)
# 노드에 그룹 번호 번호 매기기
group = [-1]*(N+1)
for idx,scc in enumerate(SCC,start=1):
for x in scc:
group[x] = idx
# 진입차수 계산
rank = [0]*(len(SCC)+1)
for x in range(1,N+1):
for nx in G[x]:
if group[x] != group[nx]:
rank[group[nx]] += 1
print(rank[1:].count(0))
코멘트
- 쉽지않음
'Algorithm > Graph' 카테고리의 다른 글
[파이썬] SWEA 1267 : 작업 순서 (test) (0) | 2025.03.09 |
---|---|
[파이썬] SWEA 1247 : 최적 경로 (D5) (0) | 2025.03.09 |
[파이썬, 자바] 백준 1506 : 경찰서 (플레5) (0) | 2025.03.09 |
[파이썬] 백준 2150 : Strongly Connected Component (플레5) (0) | 2025.03.07 |
[파이썬] 백준 16475 : 수학 미로 (골드1) (0) | 2025.03.07 |
[파이썬] 백준 22956 : 소나기 (골드1) (0) | 2025.03.06 |
[파이썬] 백준 30894 : 유령의 집 탈출하기 (골드1) (0) | 2025.03.03 |
댓글