ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준-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


    댓글

Designed by Tistory.