2668-g5 성공
This commit is contained in:
63
workbook_8708/gold/2668-g5.py
Normal file
63
workbook_8708/gold/2668-g5.py
Normal 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가지로 나눠서 진행해야한다.
|
||||
"""
|
||||
Reference in New Issue
Block a user