본문 바로가기

Tech/Problem Solving

[백준 9466] 텀 프로젝트 (Java)

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

 

9466번: 텀 프로젝트

문제 이번 가을학기에 '문제 해결' 강의를 신청한 학생들은 텀 프로젝트를 수행해야 한다. 프로젝트 팀원 수에는 제한이 없다. 심지어 모든 학생들이 동일한 팀의 팀원인 경우와 같이 한 팀만 있을 수도 있다. 프로젝트 팀을 구성하기 위해, 모든 학생들은 프로젝트를 함께하고 싶은 학생을 선택해야 한다. (단, 단 한 명만 선택할 수 있다.) 혼자 하고 싶어하는 학생은 자기 자신을 선택하는 것도 가능하다. 학생들이(s1, s2, ..., sr)이라 할 때, r=

www.acmicpc.net

접근 방법

일반적인 DFS로 접근하여 시도를 했는데 런타임 에러가 발생했다.

1
5
2 3 4 5 4

위 케이스와 같이 5 -> 4 -> 5 -> 4 ... 의 경우 overflow 에러가 발생하면서 런타임에러가 일어나는 것이 문제가 되었다.

 

구현한 코드를 싹 갈아엎고 처음부터 다시 짰다. (알고리즘 마스터의 길은 멀고도 험하다...)

방문했는지 여부를 확인하는 isVisted 배열과 함께

팀 배정 결과를 담는 isDone 배열을 더 추가하였다.

 

문제에서 주어진 케이스를 예시로 들어보면

4, 7, 6 이 한 팀을 이루게 되는데

dfs(4)를 시도함으로써 이미 dfs(7), dfs(6)의 결과까지 도출하기 때문에

main에서 이미 팀 배정 결과가 나온 index는 탐색하지 않아도 됨을 표시해야 시간을 절약할 수 있다.

시간 효율 처리를 위해서 isDone 배열을 하나 더 사용하는 것이다.

[참고] https://geehye.github.io/baekjoon-9466/#

 

소스 코드

package beckjoon;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class BaekJoon9466 {
    private static int T;
    private static int n;
    private static int[] students;
    private static boolean[] isVisited;
    private static boolean[] isDone;
    private static int count;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        T = scanner.nextInt();

        StringBuilder stringBuilder = new StringBuilder();
        List<Integer> numbers = new ArrayList<>();

        for (int j = 0; j < T; j++) {
            n = scanner.nextInt();
            numbers.clear();

            students = new int[n + 1];
            isVisited = new boolean[n + 1];
            isDone = new boolean[n + 1];
            count = 0;

            for (int i = 1; i <= n; i++) {
                students[i] = scanner.nextInt();
            }


            for (int i = 1; i <= n; i++) {
                if (!isDone[i]) {
                    dfs(i);
                }
            }

            stringBuilder.append(n - count);
            stringBuilder.append("\n");
        }

        System.out.println(stringBuilder.toString().trim());
    }

    private static void dfs(int now) {
        if (isVisited[now]) {
            isDone[now] = true;
            count++;
        } else {
            isVisited[now] = true;
        }

        int next = students[now];

        if (!isDone[next]) {
            dfs(next);
        }

        isVisited[now] = false;
        isDone[now] = true;
    }
}
반응형

'Tech > Problem Solving' 카테고리의 다른 글

[백준 2583] 영역 구하기 (Java)  (0) 2020.02.29
[백준 2636] 치즈 (Java)  (0) 2020.02.28
[백준 7569] 토마토 (Java)  (0) 2020.02.25
[백준 7576] 토마토 (Java)  (0) 2020.02.25
[백준 2206] 벽 부수고 이동하기 (Java)  (0) 2020.02.25