본문 바로가기
알고리즘 & PS

[BOJ] 텀 프로젝트 (9466, G3)

by 다람이도토리 2024. 11. 24.

DFS로 풀 수 있는 문제. 좀 까다로운 문제이다.

문제의 핵심은 "사이클"을 찾아 내는 것이다. 하나의 원소를 넣고, 돌면서 방문 여부를 체크하게 된다. 이 때, 이동한 경로를 넣고, 이미 방문했는데, 사이클 리스트에 있다면 사이클이라고 판단, 반환하는 것이다.

문제는, 사이클에서 일부 삐져나온 상황이다. (2 4 7 3 4 7 3.... 이렇게 도는 상황) 이를 주의해서 구현한다.

import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**6)

def dfs(cur_std, cur_result):
    visited[cur_std] = True
    cur_cycle.append(cur_std)
    next_std = std_list[cur_std]
    
    if visited[next_std]:
        if next_std in cur_cycle:
            # 사이클이 돌고 있다. 다음 학생의 위치를 찾아 리스트를 자른다.
            cur_result += cur_cycle[cur_cycle.index(next_std):]
    else:
        dfs(next_std, cur_result)        
          
t = int(input())
for _ in range(t):
    answer = 0
    std = int(input())
    std_list = [0] + list(map(int, input().split()))
    visited = [False] * (std + 1)
    cur_result = []
    for i in range(1, std+1):
        if not visited[i]:
            cur_cycle = []
            dfs(i, cur_result)        
    print(std - len(cur_result))

'알고리즘 & PS' 카테고리의 다른 글

[BOJ] n제곱 계산 (12728, P1)  (0) 2024.11.25
[BOJ] 파이프 옮기기 1 (17070, G5)  (0) 2024.11.24
[BOJ] 귤나무 (31005, G1)  (0) 2024.11.22
[BOJ] 도서관 (1461, G4)  (1) 2024.11.21
[BOJ] 2048 (Easy) (12100, G1)  (1) 2024.11.21