본문 바로가기
PS/백준

[백준 *Java] - 트리의 지름(1167)

by Jman 2022. 4. 22.

트리의 지름

 

1167번: 트리의 지름

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

www.acmicpc.net

 

문제

트리의 지름이란, 트리에서 임의의 두 점 사이의 거리 중 가장 긴 것을 말한다. 트리의 지름을 구하는 프로그램을 작성하시오.

입력

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

먼저 정점 번호가 주어지고, 이어서 연결된 간선의 정보를 의미하는 정수가 두 개씩 주어지는데, 하나는 정점번호, 다른 하나는 그 정점까지의 거리이다. 예를 들어 네 번째 줄의 경우 정점 3은 정점 1과 거리가 2인 간선으로 연결되어 있고, 정점 4와는 거리가 3인 간선으로 연결되어 있는 것을 보여준다. 각 줄의 마지막에는 -1이 입력으로 주어진다. 주어지는 거리는 모두 10,000 이하의 자연수이다.

출력

첫째 줄에 트리의 지름을 출력한다.


👇 접근방식

더보기

일단 나와있는 테스트 케이스를 그려보았습니다.

그려보니깐, 인접해있는 노드들 가운데, 노드와 노드를 쭉 늘렸을 때, 길이가 가장 긴 첫 노드와 끝 노드의 사이의 간선 값을 다 더해준 값이 트리의 지름을 나타내는 말이였습니다.

구하는 방식이 어려워서 구글링을 통해서 문제를 익히는 방법으로 구현했습니다.

추가로 간략하게 증명을 다른 분 블로그를 참고하면서 정리한 게 있습니다.

https://devnuts.tistory.com/78 위 링크로 들어가서 한 번 보고 오시고,

이해가 안되면... 다른 분 것과 참고하셔도 좋을 거 같습니다.


 

DFS와 BFS 방식으로 다 풀 수 있는 문제지만,

DFS 문제로 문제를 풀어보겠습니다 !

 

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

public class Boj_트리의지름 {

    static int V; // 트리의 정점의 개수
    static ArrayList<ArrayList<Node>> nodeList = new ArrayList<>();
    static boolean[] visited;
    static int max, farNode;

    static class Node {
        int data;
        int edge;

        public Node(int data, int edge) {
            this.data = data;
            this.edge = edge;
        }
    }

    static void dfs(int data, int disSum) {
        visited[data] = true;
        
        // 가장 먼 노드 data 최신화
        if (disSum > max) {
            max = disSum;
            farNode = data;
        }
        
        // recur
        for (Node childData : nodeList.get(data)) {
            if (!visited[childData.data]) {
                visited[childData.data] = true;
                dfs(childData.data, childData.edge + disSum);
            }
        }
    }

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

        // list 초기화
        for (int i = 0; i < V + 1; i++) {
            nodeList.add(new ArrayList<>());
        }

        // 노드리스트 초기화
        for (int i = 0; i < V; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int node = Integer.parseInt(st.nextToken());

            String tmp;
            while (!(tmp = st.nextToken()).equals("-1")) {
                int data = Integer.parseInt(tmp);
                int edge = Integer.parseInt(st.nextToken());

                nodeList.get(node).add(new Node(data, edge));
            }
        }

        visited = new boolean[V + 1];
        dfs(1, 0);
        visited = new boolean[V + 1];
        dfs(farNode, 0);

        System.out.println(max);
    }
}