Coding Test/백준

[백준] 1167 트리의 지름 - 자바

lsh2613 2023. 9. 16. 14:42

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

 

1167번: 트리의 지름

트리가 입력으로 주어진다. 먼저 첫 번째 줄에서는 트리의 정점의 개수 V가 주어지고 (2 ≤ V ≤ 100,000)둘째 줄부터 V개의 줄에 걸쳐 간선의 정보가 다음과 같이 주어진다. 정점 번호는 1부터 V까지

www.acmicpc.net

문제 풀이

트리의 지름을 구하는 문제로 그래프 탐색을 사용하여 해결할 수 있다. 필자는 재귀를 통한 dfs로 구현하였다.

 

이 문제에서 중요한 점은 어떤 노드부터 시작해야 가장 긴 길이 즉, 지름을 구할 수 있는지이다. 모든 노드를 탐색하여 최대치를 업데이트 할 수 있지만 2번의 dfs를 통해 높이를 구할 수 있다.

 

임의의 노드에서 시작해 그 노드가 갖는 최대 길이에 해당하는 노드를 A라고 했을 때 이 트리의 높이는 A에서 dfs를 통해 구한 길이이다.

말로하면 헷갈리니 간단하게 문제 예시를 통해 알아보자. 다음과 같은 트리가 있다.

이 트리는 한 눈에 봐도 1-3-4-5의 노드를 거쳐 총 지름이 11이 나와야 한다. 즉, 이 트리의 지름은 1또는 5에서 시작하여 지름을 구할 수 있을 것이다. 이제 임의의 노드를 선택하여 가장 긴 길이를 갖는 노드를 찾아보자.

 1, 3, 4 노드를 dfs를 수행할 경우 가장 긴 길이를 갖는 노드는 5
2, 5 노드를 dfs를 수행할 경우 가장 긴 길이를 갖는 노드는 1

즉, 2번의 dfs를 통해 트리의 높이를 구하는 과정을 살펴보았다.

 

 

코드

package 백준;

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

class Node{
    int idx;
    int distance;

    public Node(int idx, int distance) {
        this.idx = idx;
        this.distance = distance;
    }
}

public class b1167 {
    static List<Node>[] tree;
    static int N;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());

        tree = new ArrayList[N + 1];
        for (int i = 1; i <= N; i++) {
            tree[i] = new ArrayList<>();
        }
        //init
        for (int i = 0; i < N; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int from = Integer.parseInt(st.nextToken());

            while (true) {
                int to = Integer.parseInt(st.nextToken());
                if (to == -1) break;

                int cost = Integer.parseInt(st.nextToken());
                tree[from].add(new Node(to, cost));
            }
        }
        visit = new boolean[N + 1];

        dfs(1,0 );
        visit = new boolean[N + 1];

        dfs(maxDistanceIdx, 0);

        System.out.println(maxDistance);
    }

    static boolean visit[];
    static int maxDistance = 0;
    static int maxDistanceIdx = 0;
    public static void dfs(int idx, int distance) {

        if(distance > maxDistance) {
            maxDistance = distance;
            maxDistanceIdx = idx;
        }
        visit[idx] = true;

        for(int i = 0; i < tree[idx].size(); i++) {
            Node adj = tree[idx].get(i);
            int adjIdx = adj.idx;
            if(visit[adjIdx] == false) {
                dfs(adjIdx, adj.distance + distance);
                visit[adjIdx] = true;
            }
        }

    }
}