[백준]트리 with Java

hyeok ryu·2024년 3월 7일
0

문제풀이

목록 보기
92/154

문제

https://www.acmicpc.net/problem/1068


입력

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


출력

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


풀이

제한조건

  • N은 50보다 작거나 같은 자연수이다.

접근방법

단순 탐색

단순 DFS를 이용한 탐색으로 해결할 수 있다.
다만, 주의할 점이 몇가지 있는데, 주의할 점을 기준으로 생각해 보자.

1. 루트 노드가 0이 아닌경우.
2. 이진트리가 아닌 경우.
3. 루트 노드가 제거되는 경우.

1. 루트 노드가 0이 아닌경우.
문제의 예시는 모두 루트 노드가 0으로 주어져있다.
하지만 문제의 제한조건으로 항상 0이라는 말은 없다.

5
1 2 5 5 -1
3

위와 같은 예시가 있는 경우를 충분히 고려해야 한다.

2. 이진트리가 아닌 경우.

5
1 2 3 4 -1
3

위와 같은 입력이 있다고 생각해보자.
하나가 지워지면서 루트 노드만 남았다.

또는

5
1 2 3 4 -1
2

이런 입력일 경우 역시 마찬가지이다.

3. 루트 노드가 제거되는 경우

5
1 2 3 4 -1
4

루트 노드가 바로 제거되는 경우도 존재한다.
이런 경우 정답이 0이 된다.

위 3가지 경우를 어떻게 처리할 지 생각하며 DFS를 통해 순회하면 해결가능하다.


코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class Main {
	static int N, count;
	static List<Integer>[] list;

	public static void main(String[] args) throws Exception {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

		N = stoi(in.readLine());
		String[] inputs = in.readLine().split(" ");

		list = new List[N];
		for (int i = 0; i < N; ++i)
			list[i] = new ArrayList<>();
		int root = -1;
		for (int i = 0; i < N; ++i) {
			int value = stoi(inputs[i]);
			if (value == -1) {
				root = i;
				continue;
			}
			list[value].add(i);
		}

		int remove = stoi(in.readLine());
		count = 0;
		dfs(root, remove);
		System.out.println(count);
	}

	private static int dfs(int start, int remove) {
		if (start == remove)
			return -1;
		if (list[start].size() == 0) {
			count++;
			return 0;
		}
		for (int i = 0; i < list[start].size(); i++) {
			int value = dfs(list[start].get(i), remove);
			if (value == -1 && list[start].size() == 1)
				count++;
		}
		return 0;
	}

	public static int stoi(String s) {
		return Integer.parseInt(s);
	}
}

0개의 댓글