알고리즘/BOJ 문제풀이

[백준] 1135 뉴스 전하기

4Legs 2021. 2. 10. 16:35

문제 링크 : www.acmicpc.net/problem/1135

 

1135번: 뉴스 전하기

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

www.acmicpc.net

[문제 유형]

Tree DP, Greedy

 

만약 한 사원에 대해, 그 사원의 직속 부하(즉, 인접 자식 노드)로부터 전파가 완료되는 시간을 모두 알고 있다고 가정해보자.

이 때, 전파 시간이 오래 걸리는 사원에게 먼저 전파하는 것이 총 전파 시간을 줄이는 데 반드시 좋을 것이다. 직속 부하에게는 한 번에 한 명에게만 전파가 가능하기 때문이다.

따라서 각 직속 부하들로부터 완료되는 전파 시간들을 큰 순으로 정렬하고, 이들의 순서만큼 직속 부하에게 직접 전파하는 시간(첫 번째로 전달하는 직속 부하라면 1분, 두 번째라면 2분 ...)을 더해 최댓값을 구한다.

이 최댓값이 곧 현재 사원에서 전파하여 그 사원을 root로 하는 서브트리 전체에 전파하기까지의 최소 시간이 된다.

 

[코드]

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
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <cmath>
#include <memory.h>
 
#define INF 1000000007
 
using namespace std;
typedef pair<intint> p;
typedef long long ll;
 
int n;
vector<int> adj[51];
 
bool cmp(int a, int b) {
    return a > b;
}
 
int get_time(int node, int pnode) {
    int ret = 0;
    vector<int> res;
    for (int i = 0; i < adj[node].size(); i++) {
        int child = adj[node][i];
        res.push_back(get_time(child, node));
    }
 
    sort(res.begin(), res.end(), cmp);
    for (int i = 0; i < res.size(); i++) {
        ret = max(ret, res[i] + i + 1);
    }
    //printf("ret value at %d is %d\n", node, ret);
 
    return ret;
}
 
void init() {
    int parent;
    cin >> n;
 
    for (int i = 0; i < n; i++) {
        cin >> parent;
        if (parent == -1continue;
        adj[parent].push_back(i);
    }
}
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(NULL);
 
    init();
    int answer = get_time(0-1);
    printf("%d\n", answer);
 
    //system("PAUSE");
    return 0;
}
 
cs