[백준][2250번] 트리의 높이와 너비
Updated:
문제 URL
https://www.acmicpc.net/problem/2250
트리의 순회
트리의 순회 방법에는 3가지 종류가 있다.
- 프리오더
- 노드방문
- 왼쪽 자식 노드를 루트로 하는 서브 트리 프리오더
- 오른쪽 자식 노드를 루트로 하는 서브 트리 프리오더
- 인오더
- 왼쪽 자식 노드를 루트로 하는 서브 트리 프리오더
- 노드방문
- 오른쪽 자식 노드를 루트로 하는 서브 트리 프리오더
- 포스트오더
- 왼쪽 자식 노드를 루트로 하는 서브 트리 프리오더
- 오른쪽 자식 노드를 루트로 하는 서브 트리 프리오더
- 노드방문
*자식의 정보를 이용해서 현재의 계산을할때 포스트오더 사용! 반면, 부모의 정보를 이용해서 자식의 정보를 이용하면 프리오더
전체 풀이
이 문제의 경우 트리의 순회 방법 중 ‘인오더’ 방식을 사용한다. 한 노드를 기준으로 왼쪽 자식노드가 끝나야 자신노드의 열을 채워넣을 수 있기때문이다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static class Node {
int left, right;
Node(int left, int right) {
this.left = left;
this.right = right;
}
}
public static Node[] a;
public static int cnt = 0;
public static int[][] dp;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
a = new Node[n+1];
// dp[i][j]
// i : 깊이
// j : 0 - 해당 깊이의 최솟값 1 - 최댓값
dp = new int[n+1][2];
//루트노드 구하기위한 변수
int[] cnt = new int[n+1];
for(int i=0; i<=n; i++){
for(int j=0; j<2; j++){
dp[i][j] = -1;
}
}
for(int i=0; i<n; i++){
StringTokenizer stk = new StringTokenizer(br.readLine());
int x = Integer.parseInt(stk.nextToken());
int y = Integer.parseInt(stk.nextToken());
int z = Integer.parseInt(stk.nextToken());
a[x] = new Node(y, z);
if(y!=-1) cnt[y] += 1;
if(z!=-1) cnt[z] += 1;
}
//루트노드 구하는 과정
int root=0;
for(int i=1; i<=n; i++){
if(cnt[i] == 0){
root = i;
}
}
cal(root, 1);
int maxDepth = 0;
int maxNum = 0;
for(int i=1; i<=n; i++){
if(dp[i][1] == -1)
break;
int m = dp[i][1] - dp[i][0] + 1;
if(maxNum < m){
maxNum = m;
maxDepth = i;
}
}
System.out.println(maxDepth +" " + maxNum);
}
//인오더 방식의 트리순회방식
public static void cal(int x, int depth){
if(x == -1) return;
cal(a[x].left, depth+1);
//cnt는 열을 뜻한다.
cnt++;
if(dp[depth][0] == -1)
dp[depth][0] = cnt;
dp[depth][1] = cnt;
cal(a[x].right, depth+1);
}
}
느낀점
처음에 틀렸던 이유는 루트노드를 무의식적으로 1로 가정하고 풀었다. 문제 예시에서도 그랬어서 1이 당연히 루트노드라고 생각한 실수를 저질렀다.
1이 루트노드가 아닐 수 있으므로 직접 구하는방식으로 풀었다.
Leave a comment