문제 : https://www.acmicpc.net/problem/15681


문제해석

 루트가 정해진 트리가 주어졌을 때, 임의의 노드의 SubTree의 크기를 구하자.

 이때, 트리가 이진트리! 라는 말이 없으므로 조심해야한다.

문제핵심

 이 문제의 핵심은 SubTree의 크기를 구해야되는 쿼리가 10^5번 들어올 수 있기 때문에, 처음에 Root부터 시작해서 모든 노드의 SubTree의 크기를 구해둬야한다. ( 그렇게 안해도 시간 초과가 안나오는지는 모르겠습니다! ) 쿼리마다 구하면 아마 시간초과가 나올 것 같다.

알고리즘

 TreeDp를 이용해서 Root 부터 시작해서 재귀적으로 모든 노드들의 SubTree 의 크기를 구해야한다. 현재 노드가 연결된 노드들이 이미 다 방문한 노드라면, 해당 노드는 leaf 노드 이므로 Dp 값은 0이고, 1을 return 해주면 된다. leaf 노드가 아니라면 자식 노드들의 subTree 값을 모두 더해서 저장하고, 자기 자신을 포함해서 subTree + 1 값을 return 해주면 된다.

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
#include<iostream>
#include<vector>
using namespace std;
int subtree[100001];
vector<int> tree[100001];
bool visited[100001];
int countSubtree(int cur) {
    // 연결된 애들 중에 더 이상 체크할게 없을 때 --> leaf 노드일 때 1
    bool check = false;
    int sum = 0;
    for (int i = 0; i < tree[cur].size(); i++) {
        int next = tree[cur][i];
        if (!visited[next]) {
            visited[next] = 1;
            sum += countSubtree(next);
            check = true;
        }
    }
    if (!check) return 1;
    subtree[cur] = sum;
    return subtree[cur] + 1;
}
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int N, R, Q, u, v;
    cin >> N >> R >> Q;
    for (int i = 0; i < N - 1; i++) {
        cin >> u >> v;
        tree[u].push_back(v);
        tree[v].push_back(u);
    }
    visited[R] = 1;
    countSubtree(R);
    for (int i = 0, x; i < Q; i++) {
        cin >> x;
        cout << subtree[x] + 1 << '\n';
    }
    return 0;
}
cs

 

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

[BOJ] 18809 : Gaaaaaaaaaarden  (0) 2020.07.02
[BOJ] 3109 : PLINOVOD  (0) 2020.07.01
[BOJ] 18235 : 지금 만나러 갑니다  (0) 2020.06.25
[BOJ]15591 : MooTube(Silver)  (0) 2020.06.22
[BOJ] 10021 : Watering the Fields  (0) 2020.06.22

+ Recent posts