diff --git a/workbook_8708/gold/2668-g5.py b/workbook_8708/gold/2668-g5.py new file mode 100644 index 0000000..fd770df --- /dev/null +++ b/workbook_8708/gold/2668-g5.py @@ -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가지로 나눠서 진행해야한다. +"""