[백준] 1068번 - 트리 Python, Java

19842 단어 tree트리백준DFSDFS

문제


트리에서 리프 노드란, 자식의 개수가 0인 노드를 말한다.
트리가 주어졌을 때, 노드 하나를 지울 것이다. 그 때, 남은 트리에서 리프 노드의 개수를 구하는 프로그램을 작성하시오. 노드를 지우면 그 노드와 노드의 모든 자손이 트리에서 제거된다.
예를 들어, 다음과 같은 트리가 있다고 하자.

현재 리프 노드의 개수는 3개이다. (초록색 색칠된 노드) 이때, 1번을 지우면, 다음과 같이 변한다. 검정색으로 색칠된 노드가 트리에서 제거된 노드이다.

이제 리프 노드의 개수는 1개이다.

입력


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

출력


첫째 줄에 입력으로 주어진 트리에서 입력으로 주어진 노드를 지웠을 때, 리프 노드의 개수를 출력한다.

예제 입력 1


5
-1 0 0 1 1
2

예제 출력 1


2

나머지 예제는 생략한다.

풀이


Python

import sys
input = sys.stdin.readline

n = int(input().rstrip()) # 노드의 개수
p = list(map(int,input().rstrip().split())) # 노드의 부모
d_n = int(input().rstrip()) # 지울 노의 번호
tree = [[] for _ in range(n+1)]
cnt = 0
root = -1

def dfs(node):
    global tree,cnt,d_n
    if not tree[node]: # 해당 노드의 자식 노드가 없는 경우
        cnt+=1
        return
    
    for i in range(len(tree[node])): # 해당 노드의 자식 수 만큼 반복
        if tree[node][i] == d_n: # 자식노드가 삭제할 노드인 경우
            if len(tree[node]) == 1: # 자식노드의 개수가 1개인 경우
                cnt +=1 # 부모노드가 리프노드가 되므로 cnt 1 증가
            else:
                continue
        else:
            dfs(tree[node][i]) # 자식 노드를 매개변수로 dfs를 돌린다.

for i in range(len(p)):
    if p[i] == -1:
        root = i
    else:
        tree[p[i]].append(i) # 부모노드에 자식노드 넣기

if d_n == root:
    print(0)
else:
    dfs(root)
    print(cnt)

Java

import java.util.*;
import java.io.*;

public class Main {

    public static ArrayList<Integer>[] tree;
    public static int answer = 0;
    public static int delete_num;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        tree = new ArrayList[n+1];
        for(int i = 0; i<=n;i++) {
            tree[i] = new ArrayList<>();
        }
        int[] parents = new int[n];
        for(int i = 0; i<n; i++) {
            parents[i] = sc.nextInt();
        }
        delete_num = sc.nextInt();
        int root = -1;

        for(int i = 0; i<parents.length; i++) {
            if(parents[i]== -1) root = i;
            else tree[parents[i]].add(i);
        }
        if(delete_num == root) System.out.println(0);
        else {
            dfs(root);
            System.out.println(answer);
        }

    }

    public static void dfs(int node) {
        if(tree[node].size() == 0) {
            answer++;
            return;
        }

        for(int i = 0; i < tree[node].size(); i++) {
            if(tree[node].get(i) == delete_num) {
                if(tree[node].size() == 1) answer++;
            }
            else {
                dfs(tree[node].get(i));
            }
        }
    }
}

정리


  • 입력된 부모 배열을 통해 tree를 구성하고, 자식이 없으면 값을 1씩 증가시킨다.
  • 자식노드를 삭제하게 되는 경우 자식의 개수가 1이면 부모가 리프가 되므로 1을 증가 시키고 아니면 다시 dfs를 통해서 끝을 찾아 나간다.

좋은 웹페이지 즐겨찾기