반응형

문제 링크: https://www.acmicpc.net/problem/2250

 

2250번: 트리의 높이와 너비

첫째 줄에 노드의 개수를 나타내는 정수 N(1 ≤ N ≤ 10,000)이 주어진다. 다음 N개의 줄에는 각 줄마다 노드 번호와 해당 노드의 왼쪽 자식 노드와 오른쪽 자식 노드의 번호가 순서대로 주어진다. 노드들의 번호는 1부터 N까지이며, 자식이 없는 경우에는 자식 노드의 번호에 -1이 주어진다.

www.acmicpc.net

<문제 풀이> 트리

트리의 루트를 기준으로 왼쪽 서브 트리, 오른쪽 서브 트리를 각각 중위 순회하면 노드들의 열 번호를 알 수 있습니다.


왼쪽 서브트리를 중위 순회한 결과는 (8, 4, 2, 14, 9, 18, 15, 5, 10)
오른쪽 서브트리를 중위 순회한 결과는 (16, 11, 6, 12, 3, 17, 19, 13, 7)


그러면 벡터에 다음을 4가지를 push 하면 인덱스로 트리에서 각 정점의 열 번호를 알 수 있습니다.

 

1. 인덱스를 1부터 사용하기위해 0 push

2. 루트의 왼쪽 서브트리 중위 순회 결과 push

3. 루트 push

4. 루트의 오른쪽 서브트리 중위 순회 결과 push

 

vector = (0, 8, 4, 2, 14, 9, 18, 15, 5, 10, 1, 16, 11, 6, 12, 3, 17, 19, 13, 7)

 

그리고 이제 bfs로 레벨 순회를 해서 각 정점의 레벨을 알아낸 뒤 레벨별로 너비의 최댓값을 구하면 됩니다.

 

<C++ 소스 코드>

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
 
int n;
int lc[10001];
int rc[10001];
int level[10001];
bool isRoot[10001];
vector<int> col;
 
 
int getRoot() {
    for (int i = 1; i <= n; i++) {
        if (lc[i] != -1) isRoot[lc[i]] = false;
        if (rc[i] != -1) isRoot[rc[i]] = false;
    }
    for (int i = 1; i <= n; i++if (isRoot[i]) return i;
}
 
/*레벨 순회*/
void bfs(int root) {
    queue<int> q;
    q.push(root);
    level[root] = 1;
    while (!q.empty()) {
        int cur = q.front();
        q.pop();
        if (lc[cur] != -1) {
            q.push(lc[cur]);
            level[lc[cur]] = level[cur] + 1;
        };
        if (rc[cur] != -1) {
            q.push(rc[cur]);
            level[rc[cur]] = level[cur] + 1;
        }
    }
}
 
/*중위 순회*/
void inorder(int root) {
    if (lc[root] != -1) inorder(lc[root]);
    col.push_back(root);
    if (rc[root] != -1)inorder(rc[root]);
}
 
int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
 
    cin >> n;
 
    fill(lc, lc + 10001-1);
    fill(rc, rc + 10001-1);
 
    for (int i = 0; i < n; i++) {
        int v, l, r;
        cin >> v >> l >> r;
        lc[v] = l;
        rc[v] = r;
        isRoot[v] = true//처음엔 모든 정점을 root로 가정
    }
 
 
    int root = getRoot();
    bfs(root); // 레벨 순회
    col.push_back(0); // 열 인덱스를 1부터 사용하기 위함
    if (lc[root] != -1) inorder(lc[root]); // 루트의 왼쪽 노드 col 벡터에 추가
    col.push_back(root); // root 노드 col 벡터에 추가
    if (rc[root] != -1) inorder(rc[root]); // 루트의 오른쪽 노드 col 백터에 추가
 
    int size = col.size();
    int width = 0;
    int min_level = 10000;
 
    for (int s = 1; s < size; s++) {
        for (int e = size - 1; e >= s; e--) {
            if (level[col[s]] == level[col[e]]) {
                if (e - s + 1 == width) {
                    width = e - s + 1;
                    min_level = min(min_level, level[col[s]]);
                }
                else if (e - s + 1 > width) {
                    min_level = level[col[s]];
                    width = e - s + 1;
                }
                break;
            }
        }
    }
 
    cout << min_level << " " << width;
    return 0;
}
cs

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 2623번] 음악프로그램  (0) 2020.04.11
[백준 2252번] 줄 세우기  (0) 2020.04.03
[백준 11725번] 트리의 부모 찾기  (0) 2020.03.26
[백준 1043번] 거짓말  (0) 2020.03.25
[백준 6118번] 숨바꼭질  (0) 2020.03.23

+ Recent posts