๋ฌธ์
https://www.acmicpc.net/problem/2252
๋ฐฑ์ค ๋ฌธ์ ์ง - 0x1A๊ฐ - ์์ ์ ๋ ฌ
์๊ณ ๋ฆฌ์ฆ: ์์ ์ ๋ ฌ
ํ์ด

์์ ์ ๋ ฌ ์์ฒด๋ฅผ ์ฒ์ ์ ํด๋ดค๋ ํํธ๋ค.
์์์ ๋ ฌ(Topological Sorting): DAG(๋ฐฉํฅ ์ฌ์ดํด์ด ์๋ ๋ฐฉํฅ ๊ทธ๋ํ)์ ๋
ธ๋๋ค์ ์์ํ
BFS, DFS ๋ชจ๋ ๊ฐ๋ฅ. ๊ทธ๋ํ๋ ๋จ๋ฐฉํฅ์ผ๋ก ์ ์ฅํ๋ค.
์ ์ฒด ์ฝ๋
1๏ธโฃ DFS ๋ฐฉ์
# 1. DFS ์ฌ์ฉ
# ์ง์
์ฐจ์(in-degree) ๋ถํ์
# ๋ฉ๋ชจ๋ฆฌ: 39328KB / ์๊ฐ: 156ms
from sys import stdin
input = stdin.readline
N, M = map(int, input().split())
graph = [[] for _ in range(N+1)]
for _ in range(M):
u, v = map(int, input().split())
graph[u].append(v)
def dfs():
stack = []
visited = [False] * (N+1)
ret = []
for i in range(1, N+1):
if visited[i]:
continue
stack.append((i, False))
while stack:
curr, is_done = stack.pop() # (ํ์ฌ ๋
ธ๋, ํ์ฒ๋ฆฌ ์ฌ๋ถ)
if is_done: # โ
ํ์ฒ๋ฆฌ ๋จ๊ณ - ์์ ๋
ธ๋๋ฅผ ๋ชจ๋ ๋ฐฉ๋ฌธ ํ ๋ณธ์ธ ๋
ธ๋ ์ฒ๋ฆฌ
ret.append(curr)
continue
if visited[curr]: # ์ด๋ฏธ ๋ฐฉ๋ฌธํ ๋
ธ๋๋ฉด ๋ฌด์
continue
visited[curr] = True # ํ์ฌ ๋
ธ๋ ๋ฐฉ๋ฌธ์ฒ๋ฆฌ, ํ์ฒ๋ฆฌ๋ฅผ ์ํด ๋ค์ push
stack.append((curr, True))
for node in graph[curr]:
if not visited[node]:
stack.append((node, False))
return ret[::-1] # ๋ค์ง์ด์ ๋ฐํ
print(*dfs())
์ฌ๊ท๊ฐ ์๋ ๋จ์ ๋ฐ๋ณต์ผ๋ก DFS๋ฅผ ์ํํ๊ธฐ ๋๋ฌธ์, is_done์ผ๋ก ๋ฐฉ๋ฌธ ์์ /ํ์ฒ๋ฆฌ ์์ ์ ๊ตฌ๋ถํด์ค์ผํ๋ค.
(๋ฌผ๋ก ๊ทธ๋ํ๊ฐ 1 - 4 - 3 - 6... ์ด๋ฐ์์ผ๋ก ์ต์ ๊ฐ์ ์ผ๋ก ๊ตฌ์ฑ๋์ด ์๋ค๋ฉด ํ์ X)
์คํ ๋ก์ง์ ๋ค์๊ณผ ๊ฐ๋ค.
- ๋ชจ๋ ๋ ธ๋์ ๋ํด ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋๋ฅผ ์ฐพ์ DFS ์์
- ์คํ์ ์์ ๋
ธ๋๋ฅผ
(๋ ธ๋, False)ํํ๋ก ์ฝ์ . ์ฌ๊ธฐ์False๋ ์์ง ํ์ฒ๋ฆฌ๋์ง ์์์์ ์๋ฏธํ๋ค. - ์คํ์ด ๋น ๋๊น์ง ์๋๋ฅผ ๋ฐ๋ณตํ๋ค.
- ์คํ์์
(ํ์ฌ ๋ ธ๋, ํ์ฒ๋ฆฌ ์ฌ๋ถ)๊บผ๋ด๊ธฐ - ๋ง์ฝ ํ์ฒ๋ฆฌ ์ฌ๋ถ๊ฐ True๋ผ๋ฉด,
- ๊ฒฐ๊ณผ ๋ฆฌ์คํธ์ ํ์ฌ ๋ ธ๋๋ฅผ ์ถ๊ฐ ํ ๊ณ์ ์งํ
- ๋ง์ฝ ์ด๋ฏธ ๋ฐฉ๋ฌธํ ๋
ธ๋๋ผ๋ฉด,
- ๋ฌด์ํ๊ณ ๊ณ์ ์งํ
- ์์ง ๋ฐฉ๋ฌธํ์ง ์์ ๋
ธ๋๋ผ๋ฉด,
- ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ
(visited[ํ์ฌ ๋ ธ๋] = True) - ํ์ฒ๋ฆฌ๋ฅผ ์ํด
(ํ์ฌ ๋ ธ๋, True)ํํ๋ก ๋ค์ ์คํ์ ์ถ๊ฐ - ํ์ฌ ๋
ธ๋์ ์ธ์ ๋
ธ๋ ์ค ๋ฐฉ๋ฌธํ์ง ์์ ๋
ธ๋๋ฅผ
(์ธ์ ๋ ธ๋, False)ํํ๋ก ์คํ์ ์ถ๊ฐ
- ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ
- ์คํ์์
- ๋ชจ๋ ๋ ธ๋์ ๋ํ ์ฒ๋ฆฌ๊ฐ ๋๋๋ฉด ๊ฒฐ๊ณผ ๋ฆฌ์คํธ๋ฅผ ๋ค์ง์ด์ ๋ฐํ
DFS๊ฐ ๋๋๋ ์๊ฐ = ํด๋น ์ ์ ๊ณผ ๊ทธ ์ ์ ์์ ๋๋ฌํ ์ ์๋ ๋ชจ๋ ์ ์ ์ ๋ฐฉ๋ฌธํ์๋
์ด๋ฏ๋ก, ๊ฒฐ๊ณผ ๋ฆฌ์คํธ์๋ ๋ ์๋ฒ๋ถํฐ ์ฐจ๋ก๋ก ๋ค์ด๊ฐ๊ฒ ๋๋ค.
๋ฐ๋ผ์ ๋ง์ง๋ง์ ๋ค์ง์ด์ค์ผ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ์์ ์ ๋ ฌ ์์๋ฅผ ์ป์ ์ ์์.
๊ทธ๋ฆฌ๊ณ ์ค๊ฐ์ if visited[curr]์กฐ๊ฑด์ด ์๋ค๋ฉด ์์์์ด ๋ค์ฃฝ๋ฐ์ฃฝ์ผ๋ก ์ฃผ์ด์ก์ ๊ฒฝ์ฐ ํ๋ฆฐ ๋ต์ด ๋์ถ๋๋ค.
# ๋ฐ๋ก
3 3
1 3
2 3
1 2
๋ต: 1 2 3
๊ฒฐ๊ณผ: 1 3 2 3
2๏ธโฃ BFS ๋ฐฉ์
# 2. BFS ์ฌ์ฉ
# ์ง์
์ฐจ์(in-degree)๋ก ์ฒดํฌ
# ๋ฉ๋ชจ๋ฆฌ: 40908KB / ์๊ฐ: 188ms
from sys import stdin
from collections import deque
input = stdin.readline
N, M = map(int, input().split())
graph = [[] for _ in range(N+1)]
degree = [0] * (N+1)
for _ in range(M):
u, v = map(int, input().split())
degree[v] += 1
graph[u].append(v)
queue = deque()
visited = [False] * (N+1)
ret = []
for i in range(1, N+1):
if not degree[i]:
queue.append(i)
visited[i] = True
def bfs():
while queue:
curr = queue.popleft()
ret.append(curr)
for node in graph[curr]:
if not visited[node]:
degree[node] -= 1
if degree[node] == 0:
queue.append(node)
visited[node] = True
bfs()
print(*ret)
์ฌ์ค ๋ BFS๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์์ด ๋ ํธํ๋ค.
๋ก์ง ์์ฒด๋ ์ต์ํ๊ฑฐ๋์ ํ๋์ ์์๋ณด๊ธฐ ์ฝ๋ค...
๋ค๋ง BFS๋ฅผ ์ฌ์ฉํ ๋์๋ ๋ ธ๋๋ค์ ์ง์ ์ฐจ์(in-degree)๋ฅผ ๋จผ์ ์ ๋ฆฌํด์ค์ผํ๋ค.
๋ญ ๋ง์ด๋ํ๋ฉด, ๋ฌธ์ ์ ๊ฐ์ด "A๊ฐ B์์ ์์ผํ๋ค"์ฒ๋ผ ์ด๋ค ํ ๋ ธ๋๊ฐ ๋ค๋ฅธ ๋ ธ๋ ์์ ์์นํด์ผํ๋ค๊ณ ํ์๋
๊ทธ๋ํ์ ํ๋ฆ์ A → B ์ ๊ฐ์ด ์ด๋ฃจ์ด์ง๋ค.
๋ฐ๋ผ์ A์ ์ง์ ์ฐจ์๋ 0, B์ ์ง์ ์ฐจ์๋ 1์ด ๋๋๊ฒ์ด๋ค.
ํ์ง๋ง ๋ฌธ์ ์ ๋ฐ๋ผ์ A๊ฐ ๋จผ์ ์คํ๋๋๊ฒ๊ฐ์๋ B → A์ ๊ฐ์ด ์ ๋ฆฌํด์ผ ํ ์๋ ์์ผ๋ฏ๋ก ์ฃผ์ํด์ผํ๋ค.
BFS๋ฐฉ์์ ์คํ ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
- ๋ชจ๋ ๋ ธ๋์ ์ง์ ์ฐจ์(in-degree)๋ฅผ ๊ณ์ฐํ๋ค.
- ์ง์
์ฐจ์๊ฐ 0์ธ ๋ชจ๋ ๋
ธ๋๋ฅผ ์ฐพ์ ํ์ ์ฝ์
ํ๋ค.
- ์ด ๋ ธ๋๋ค์ ์ ํ ์กฐ๊ฑด์ด ์์ด ๋ฐ๋ก ์์ํ ์ ์๋ ๋ ธ๋๋ค์.
- ํ๊ฐ ๋น ๋๊น์ง ์๋๋ฅผ ๋ฐ๋ณตํ๋ค.
- ํ์์ ๋ ธ๋๋ฅผ popํ๋ค.
- ๊ฒฐ๊ณผ ๋ฆฌ์คํธ์ ๊บผ๋ธ ํ์ฌ ๋ ธ๋๋ฅผ ์ถ๊ฐ.
- ํ์ฌ ๋
ธ๋์ ์ธ์ ํ ๋ชจ๋ ๋
ธ๋์ ๋ํด,
- ํด๋น ๋ ธ๋์ ์ง์ ์ฐจ์๋ฅผ 1 ๊ฐ์์ํด.
- ์ง์ ์ฐจ์๊ฐ 0์ด ๋๋ฉด ๋ ธ๋๋ฅผ ํ์ ์ฝ์ ํ ๋ฐฉ๋ฌธ์ฒ๋ฆฌํ๋ค.
- ๋ชจ๋ ๋ ธ๋๊ฐ ์ฒ๋ฆฌ๋์์ผ๋ฉด ๋. ๊ฒฐ๊ณผ ๋ฆฌ์คํธ์ ์์ ์ ๋ ฌ์ ๊ฒฐ๊ณผ๊ฐ ๊ทธ๋๋ก ์ ์ฅ๋์ด์๋ค.
๋ฌธ์ ์ ๋ฐ๋ผ ํจ์จ์ ์ธ ๋ฐฉ์์ด ๋ฌ๋ผ์ง๋ค.