Post

BOJ 1135 뉴스 전하기

BOJ 1135 뉴스 전하기

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

문제

민식이는 회사의 매니저이다. 그리고, 민식이는 회사의 중요한 뉴스를 모든 직원에게 빠르게 전달하려고 한다. 민식이의 회사는 트리 구조이다. 모든 직원은 정확하게 한 명의 직속 상사가 있다. 자기자신은 그들 자기 자신의 직접 또는 간접 상사가 아니고, 모든 직원은 민식이의 직접 또는 간접적인 부하이다.

민식이는 일단 자기 자신의 직속 부하에게 한 번에 한 사람씩 전화를 한다. 뉴스를 들은 후에, 각 부하는 그의 직속 부하에게 한 번에 한 사람씩 전화를 한다. 이 것은 모든 직원이 뉴스를 들을 때 까지 계속된다. 모든 사람은 자신의 직속 부하에게만 전화를 걸 수 있고, 전화는 정확하게 1분 걸린다. 이때 모든 직원이 소식을 듣는데 걸리는 시간의 최솟값을 구하는 프로그램을 작성하시오.

오민식의 사원 번호는 0이고, 다른 사원의 번호는 1부터 시작한다.


입력

첫째 줄에 직원의 수 N이 주어진다. 둘째 줄에는 0번 직원부터 그들의 상사의 번호가 주어진다. 0번 직원 (오민식)은 상사가 없기 때문에 -1이고, 나머지 직원 i의 상사 번호는 i보다 작거나 같은 음이 아닌 정수이다. N은 50보다 작거나 같은 자연수이다.


출력

첫째 줄에 모든 소식을 전하는데 걸리는 시간의 최솟값을 출력한다.


예제 입력 1

3
-1 0 0

예제 출력 1

2

예제 입력 2

5
-1 0 0 2 2

예제 출력 2

3

… 이하 예제 생략


코드

처음 문제를 풀었을 때, 별 생각 없이 그냥 직속 부하 직원이 많은 직원에게 먼저 소식을 전해 걸리는 시간을 계산했다.

하지만, 조금만 더 생각해보면 특정 직원의 직속 부하가 많다고 해서 그 직원의 모든 부하 직원에게 소식을 전하는 시간이 오래 걸리는 것이 아니라는 것은 알 수 있다.

조금 더 고민해 보고 Top-down 방식으로 문제를 해결할 수 있었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

    static int N;

    // 상사 직속 부하 직원들의 목록을 저장하기 위한 배열, ex) junior[0]은 0번 직원의 직속 부하 직원들의 List
    static List<Integer>[] junior;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        junior = new List[N];
        for (int i = 0; i < N; i++) {
            junior[i] = new ArrayList<>();
        }

        StringTokenizer st = new StringTokenizer(br.readLine());
        st.nextToken();
        for (int i = 1; i < N; i++) {
            int senior = Integer.parseInt(st.nextToken());

            junior[senior].add(i);
        }

        int answer = calculateMinTime(0);

        System.out.println(answer);
    }

    /**
     * 직원이 모든 직간접 부하 직원에게 소식을 전하는데 걸리는 최소 시간을 계산하는 메소드
     * @param senior 검사하려는 직원
     * @return 모든 직간접 부하 직원에게 소식을 전하는데 걸리는 최소 시간
     */
    static int calculateMinTime(int senior) {
        // 부하 직원이 없으면 소식을 전하는데 걸리는 시간은 0
        if(junior[senior].size() == 0) {
            return 0;
        }

        // 직속 부하들이 소식을 전하는데 걸리는 최소 시간들을 구함
        PriorityQueue<Integer> times = new PriorityQueue<>(Comparator.reverseOrder());

        for (int check: junior[senior]) {
            int timeOfJunior = calculateMinTime(check);

            times.offer(timeOfJunior);
        }

        // 소요 시간 중 오래 걸리는 순서로 직속 부하에게 소식을 전하며 걸리는 시간을 측정
        int time = 0;
        int queueSize = times.size();
        for (int i = 0; i < queueSize; i++) {
            time = Math.max(time, times.poll() + i);
        }

        return time + 1;
    }
}
This post is licensed under CC BY 4.0 by the author.