๋ฐฑ์ค€ 2150 Strongly Connected Component

passยท2022๋…„ 5์›” 3์ผ
0

์•Œ๊ณ ๋ฆฌ์ฆ˜

๋ชฉ๋ก ๋ณด๊ธฐ
1/35

๋ฌธ์ œ

๐Ÿ‘€ ๋ฌธ์ œ ์‚ฌ์ดํŠธ : https://www.acmicpc.net/problem/2150






ํ’€์ด

๋‚œ์ด๋„ : Platinum V

Strongly connected Component๋Š” ์ž„์˜์˜ ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ vertex v, w์— ๋Œ€ํ•ด v์—์„œ w๋กœ์˜ ๊ฒฝ๋กœ์™€ w์—์„œ v๋กœ์˜ ๊ฒฝ๋กœ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ๋ฅผ ๋งํ•œ๋‹ค.
๋Œ€ํ‘œ์ ์ธ ํ’€์ด๋ฒ•์œผ๋กœ๋Š” ์ฝ”์‚ฌ๋ผ์ฃผ(Kosaraju) ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์žˆ์–ด ํ•ด๋‹น ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ํ’€์ดํ•˜์˜€๋‹ค.

  1. ์ฃผ์–ด์ง€๋Š” ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„์— ์—ญ์ˆœ์ด ๋˜๋Š” ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„๋„ ํ•จ๊ป˜ ์ €์žฅํ•œ๋‹ค.
  2. ์ˆœ๋ฐฉํ–ฅ์œผ๋กœ ์ง„ํ–‰ํ•  dfs์™€ ์—ญ๋ฐฉํ–ฅ์œผ๋กœ ์ง„ํ–‰ํ•  dfs๋ฅผ ๋งŒ๋“ ๋‹ค.
  3. ๊ฐ vertex๋ฅผ ๋‹ด์„ stack์„ ๋งŒ๋“ ๋‹ค.
  4. ๋ชจ๋“  vertex์— ๋Œ€ํ•˜์—ฌ ์—ญ๋ฐฉํ–ฅ์œผ๋กœ dfs๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ stack์— ๊ฐ’์„ ๋„ฃ์–ด์ค€๋‹ค.
  5. stack์—์„œ ๊ฐ’์„ ํ•˜๋‚˜์”ฉ ๋นผ์˜ค๋ฉด์„œ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ vertex๋ผ๋ฉด ์ˆœ๋ฐฉํ–ฅ์œผ๋กœ dfs๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์ด dfs์—์„œ ๋งŒ๋‚˜๋Š” ๋ชจ๋“  ๋…ธ๋“œ๋Š” SCC์ธ ๊ฒƒ์„ ํ™œ์šฉํ•œ๋‹ค.

-> ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์—ญ๋ฐฉํ–ฅ์œผ๋กœ dfs๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜์—ฌ stack์— ๋„ฃ์–ด์ฃผ๊ณ , stack์—์„œ ๊ฐ’์„ ๋‹ค์‹œ ๋นผ์˜ค๋ฉด์„œ ์žฌํƒ์ƒ‰ํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ ์ธ ๋ถ€๋ถ„์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ˆœ๋ฐฉํ–ฅ์—์„œ์˜ sink๋Š” ์—ญ๋ฐฉํ–ฅ์—์„œ์˜ source์ธ ๊ฒƒ์„ ์ž˜ ์ดํ•ดํ•˜์—ฌ ํ’€์ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.






์ฝ”๋“œ

import sys

sys.setrecursionlimit(10**6)
v, e = map(int, input().split())

graph = [[] for _ in range(v+1)]
graph_reverse = [[] for _ in range(v+1)]
visited = [False] * (v+1)
visited_reverse = [False] * (v+1)

result = []
stack = []
count = -1

for i in range(e):
    a, b = map(int, input().split())
    graph[a].append(b)
    graph_reverse[b].append(a)

def dfs(x):
    result[count].append(x)
    visited[x] = True
    for i in graph[x]:
        if not visited[i]:
            dfs(i)


def dfs_reverse(x):
    visited_reverse[x] = True
    for i in graph_reverse[x]:
        if not visited_reverse[i]:
            dfs_reverse(i)

    stack.append(x)

ind = v
while v > 0:
    if visited_reverse[v]:
        v = v - 1
        continue
    dfs_reverse(v)
    v = v - 1

while stack:
    k = stack.pop()
    if visited[k]:
        continue
    count = count + 1
    result.append([])
    dfs(k)

for i in range(len(result)):
    result[i].sort()
result.sort()

print(len(result))
for r in result:
    for i in range(len(r)):
        print(r[i], end=" ")
        if i == len(r) - 1:
            print(-1)
profile
์•ˆ๋“œ๋กœ์ด๋“œ ๊ฐœ๋ฐœ์ž ์ง€๋ง์ƒ

0๊ฐœ์˜ ๋Œ“๊ธ€