ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • BOJ) 트리 (1068 번)
    알고리즘/백준 2021. 1. 29. 17:08
    반응형

    트리

     

    1068번: 트리

    첫째 줄에 트리의 노드의 개수 N이 주어진다. N은 50보다 작거나 같은 자연수이다. 둘째 줄에는 0번 노드부터 N-1번 노드까지, 각 노드의 부모가 주어진다. 만약 부모가 없다면 (루트) -1이 주어진다

    www.acmicpc.net

    풀이

     

    트리의 정보가 주어지고 특정 노드를 제거할 때, 리프노드가 몇 개 인지 찾는 문제다.

    먼저, 트리의 각 노드는 하나의 부모를 가지고 있기 때문에 find-union을 사용해야겠다고 생각했다.

    이전 find-union과 다른 점은 이미 부모에 대한 정보가 주어졌기 때문에, find할 때 더 상위 부모로 값을 최신화하지 않았다는 것이다. (최신화를 하게되면 루트 노드로 이어지기 때문에, 특정 노드를 제거했을 때, 자식노드를 제거할 수 없음)

     

    다음으로는 입력받은 제거할 노드의 vertex를 받아서 parents를 수정해주었다.

    해당 vertex의 parents를 임의로 제거됐다는 표시인 -2로 설정해주고, 이후 트리를 탐색하면서 지워지지 않은 노드를 찾았다.여기서, 자기 자신이 지워지지 않은 상태이며, 자신의 부모 노드가 지워지지 않았고, 자신은 자식 노드를 갖지 않는지 조건문을 통해 남은 리프노드를 찾았다.

     

     

    ~> 처음에는 Union을 사용해서 입력 받은 제거 노드를 부모로 갖는 노드들을 찾아 똑같이 표시를 해주려고 했지만, 오히려 불필요한 과정이라 느껴서 제외했다.

     

    코드

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
    
    public class Tree_1068 {
        static final int ROOT =-1, REMOVED =-2, ZERO =0, ADDITIONAL =1;
        static int[] parents;
    
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            int n = Integer.parseInt(br.readLine());
            parents = new int[n];
    
            StringTokenizer st = new StringTokenizer(br.readLine());
            for(int i=0; i<n; i++) {
                parents[i] = Integer.parseInt(st.nextToken());
            }
            int removeNode = Integer.parseInt(br.readLine());
    
            br.close();
            solution(removeNode, n);
        }
    
        private static void solution(int removeNode, int n) {
            parents[removeNode] = REMOVED;
            int answer =0;
    
            for(int i=0; i<n; i++) {
                if(parents[i] != REMOVED) { // 자신이 루트가 아니고 지워지지 않은 경우
                    answer += find(parents[i]) != REMOVED && !hasChildren(i) ? ADDITIONAL : ZERO;
                }
            }
            System.out.println(answer);
        }
    
        private static boolean hasChildren(int i) {
            for(int parentIdx : parents) {
                if(parentIdx == i) {
                    return true;
                }
            }
            return false;
        }
    
        private static int find(int val) {
            if(val == REMOVED) {
                return val;
            } else if(val == ROOT) {
                return val;
            }
            return find(parents[val]);
        }
    }
    
    반응형

    '알고리즘 > 백준' 카테고리의 다른 글

    BOJ) 문자열 폭발 (9935 번)  (0) 2021.01.29
    BOJ) 특정한 최단 경로 (1504 번)  (0) 2021.01.29
    BOJ) 트리의 지름 (1167 번)  (0) 2021.01.29
    BOJ) 최솟값 찾기 (11003 번)  (0) 2021.01.29
    BOJ) 전깃줄 (2565 번)  (0) 2021.01.26

    댓글

Designed by Tistory.