알고리즘/트리

[백준-2250]-[트리]-트리의 높이와 너비

팡스 2018. 11. 27. 12:10

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



이 문제는 중위 순회법으로 문제를 풀면 된다. 


중위순회법으로 문제를 접근하는 이유는  노드의 위치를 알기위해선 본인 기준 왼쪽에 있는 모든 노드들의 수를 알아야 하기 때문이다. 


그리고 이 문제에서 주의해야 할 점은 1이 무조건 루트가 아니라는거다. 


1이 루트가 아니라는 힌트를 먼저 얻은 다음에 문제에 접근해서 어렵지 않게 문제를 풀었다. 


먼저 Node 클래스를 하나 만들었다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
class Node{
    int num;
    int left;
    int right;
    int parent;
    
    public Node(int num, int left, int right, int parent) {
        this.num = num;
        this.left = left;
        this.right = right;
        this.parent = parent;
    }
}
cs

어렵게 가지 않기 위해서 부모 노드의 번호도 클래스에 추가시켰다. 

트리의 노드정보를 전부 입력 받은 뒤 parent 값이 초기 값 -1이면 그 노드가 루트라고 정했다.


각 노드는 본인 번호 포함 본인의 좌측, 우측 자식 노드의 번호도 포함한다.

이 값이 -1이면 자식 노드가 없다는 것으로 했다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    public static void dfs(int num, int level) {
        Node node = tree[num];
        
        if(maxLevel < level) maxLevel = level;
        
        if(node.left != -1) {
            dfs(node.left, level+1);
        }
        
        levelLeft[level] = Math.min(levelLeft[level], nodeIdx);
        levelRight[level] = nodeIdx++;
        
        if(node.right != -1) {
            dfs(node.right, level+1);
        }
    }
cs


위의 소스가 중위 순회로 트리를 탐색하는 소스이다. 

루트부터 본인의 자식 노드들을 탐색을 한다. 


루트를 기준으로 레벨은 1 이고 그 자식들은 2 그의 자식들은 3 으로 각 노드들의 레벨을 나타냈다. 


maxLevel을 구하는 이유는 레벨이 어디까지 내려갈지 모르기때문에 레벨의 크기를 알기 위함이다.


levelLeft, levelRight는 각 레벨의 제일 좌측 노드와 우측 노드의 번호를 저장하고 그 번호가 각 레벨의 너비를 나타낸다. 



소스

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
96
97
98
99
100
101
102
103
104
105
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    public static int size;
    public static int root;
    public static int maxLevel, nodeIdx;
    
    public static Node[] tree;
    
    public static int[] levelLeft;
    public static int[] levelRight;
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = null;
        
        size = Integer.parseInt(br.readLine());
        
        tree = new Node[size+1];
        levelLeft = new int[size+1];
        levelRight = new int[size+1];
        
        // 초기화
        for(int i=0; i <= size; i++) {
            tree[i] = new Node(i, -1-1-1);
            levelLeft[i] = size+1;
        }
        
 
        //입력받기
        for(int i=1; i <= size; i++) {
            st = new StringTokenizer(br.readLine());
            
            int num = Integer.parseInt(st.nextToken());
            int leftNum = Integer.parseInt(st.nextToken());
            int rightNum = Integer.parseInt(st.nextToken());
            
            tree[num].left = leftNum;
            tree[num].right = rightNum;
            
            if(leftNum != -1)
                tree[leftNum].parent = num;
            
            if(rightNum != -1)
                tree[rightNum].parent = num;
        }
        
        // 루트 찾기
        for(int i=1; i <= size; i++
            if(tree[i].parent == -1) root = i;
        
        nodeIdx = 1;
        dfs(root, 1);
        
        int res = 1;
        int subs = levelRight[1- levelLeft[1+ 1;
        
        for(int i=2; i <= maxLevel; i++) {
            int tmpSubs = levelRight[i] - levelLeft[i] +1;
            
            if(subs < tmpSubs) {
                res = i;
                subs = tmpSubs;
            }
        }
        
        System.out.println(res + " " + subs);
    }
    
    public static void dfs(int num, int level) {
        Node node = tree[num];
        
        if(maxLevel < level) maxLevel = level;
        
        if(node.left != -1) {
            dfs(node.left, level+1);
        }
        
        levelLeft[level] = Math.min(levelLeft[level], nodeIdx);
        levelRight[level] = nodeIdx++;
        
        if(node.right != -1) {
            dfs(node.right, level+1);
        }
    }
}
 
class Node{
    int num;
    int left;
    int right;
    int parent;
    int point;
    
    public Node(int num, int left, int right, int parent) {
        this.num = num;
        this.left = left;
        this.right = right;
        this.parent = parent;
        this.point = 1;
    }
}
cs