2668-g5 성공

This commit is contained in:
2026-02-25 11:16:26 +09:00
parent 3777344b56
commit 7bcb4dfdc4

View File

@@ -0,0 +1,63 @@
# 숫자 고르기
import sys
input = sys.stdin.readline
def dfs(v, g, n):
visited = [0] * (n+1)
stack = [v]
record = [v]
while stack:
now = stack.pop()
if visited[now]:
break
visited[now] = 1
w = g[now]
stack.append(w)
record.append(w)
target = record.pop()
result = set()
result.add(target)
while record and record[-1] != target:
result.add(record.pop())
return result
def solution():
n = int(input().rstrip())
g = {}
result = set()
for i in range(1, n+1):
g[i] = int(input().rstrip())
for i in range(1, n+1):
if i in result:
continue
result.update(dfs(i, g, n))
print(len(result))
for v in sorted(result):
print(v)
return
solution()
"""
걸린 시간: 몰라
시간 복잡도: 한 노드당 한번씩만 방문하기 때문에 O(n)이다.
해설: 그래프 모양에서 원형 부분에 해당하는 노드들이 답이라는 것은 금방 알았는데 구현이 어려웠다.
dfs로 구현했다.
본인 노드를 다시 만나게 되면 역으로 추적을 해야하기 때문에 record에 들어온 순서를 스택으로 기록하였고,
당연하게도 이미 result에 답으로 채택된 노드들은 dfs 탐색을 시작하지 않았다.
하지만 위 방식은 진출차수가 무조건 1이기 때문에 가능한 일이었다.
만약 진출차수가 1이상이었다면(제한이 없었다면) 본인 노드가 다시 만나서가 아닌, 여러 곳에서 온 것으로도 반복될 수 있기 때문이다.
이런 경우에는 dfs 재귀로 상태관리를 미방문(0), 보는중(1), 끝(2) 이렇게 3가지로 나눠서 진행해야한다.
"""