2668 숫자고르기

https://www.acmicpc.net/problem/2668

문제설명

각 노드가 다른 노드를 가리키는 그래프에서 사이클을 찾는다.

접근방식

O(N ^ 2) 시간복잡도

 

DFS를 모든 노드에서 호출하고, 각 DFS 호출 시 최대 N개의 노드를 탐색해야 하는 경우를 고려하면

전체 시간복잡도는 O(N ^ 2)이 된다.

  • N번의 DFS 호출이 각각 O(N)의 작업을 수행한다.

문제 조건 분석 과정

 

각 노드가 가리키는 노드를 1-based index에서 0-based index로 변환하여 저장한다.

 

  • 모든 노드에 대해 DFS를 실행하여 사이클을 찾는다.
  • DFS 호출 시, 방문 상태를 체크하고 재귀적으로 다음 노드로 이동한다.
  • 현재 노드가 사이클의 시작 노드와 동일하면, 사이클에 해당 노드를 추가한다.
  • 사이클을 구성하는 노드를 오름차순으로 정렬하고 출력한다.

 

전체코드

import java.util.*;
import java.io.*;

public class Main {
    static int num; // 현재 시작 노드를 저장할 변수
    static int[] arr; // 각 노드가 가리키는 노드를 저장하는 배열
    static boolean[] check; // DFS 방문 여부를 기록하는 배열
    static List<Integer> answer; // 사이클의 노드를 저장할 리스트

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 입력된 노드의 개수
        int N = Integer.parseInt(br.readLine());

        // 각 노드가 가리키는 노드를 저장할 배열 초기화
        arr = new int[N];
        check = new boolean[N];

        // 노드의 가리키는 정보를 읽어 배열에 저장
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(br.readLine()) - 1; // 1-based index를 0-based index로 변환
        }

        // 사이클을 저장할 리스트 초기화
        answer = new LinkedList<>();

        // 각 노드에 대해 DFS를 실행하여 사이클을 찾음
        for (int i = 0; i < N; i++) {
            check[i] = true; // 현재 노드를 방문중으로 표시
            num = i; // 시작 노드를 저장
            dfs(i); // DFS 호출
            check[i] = false; // DFS 종료 후 현재 노드 방문 상태 초기화
        }

        // 결과 리스트를 오름차순으로 정렬
        Collections.sort(answer);

        // 사이클의 노드 개수와 각 노드를 출력
        System.out.println(answer.size());
        for (Integer integer : answer) {
            System.out.println(integer + 1); // 0-based index를 1-based index로 변환하여 출력
        }
    }

    public static void dfs(int i) {
        // 현재 노드가 사이클의 시작 노드와 같다면, 사이클에 추가
        if (arr[i] == num) {
            answer.add(num);
        }

        // 현재 노드가 방문되지 않았다면 DFS를 계속 수행
        if (!check[arr[i]]) {
            check[arr[i]] = true; // 방문 중으로 표시
            dfs(arr[i]); // 다음 노드로 DFS 호출
            check[arr[i]] = false; // DFS 종료 후 방문 상태 초기화
        }
    }
}

'자료구조 > 문제풀이' 카테고리의 다른 글

[백준 JAVA] 1753 최단경로  (0) 2024.09.10
[백준 JAVA] 17396 백도어  (0) 2024.09.10
[백준 JAVA] 10844 쉬운 계단 수  (0) 2024.08.31
[백준 JAVA] 2309 일곱 난쟁이  (0) 2024.08.31
[백준 JAVA] 9465 스티커  (0) 2024.08.29

+ Recent posts