白準1967号(木の直径)


質問元:https://www.acmicpc.net/problem/1967
質問する
  • ツリー(ツリー)は、周期のない無方向図です.ツリーでは、どちらのノードを選択しても、2つのノードの間には常に1つのパスしか存在しません.ツリーから2つのノードを選択して両側に伸ばすと、最も長く伸びる場合があります.このとき、ツリー内のすべてのノードが、この2つのノードを直径の端点とする円内に入ります.

  • この2つのノード間のパスの長さをツリーの直径と呼びます.正確には、ツリーのすべてのパスの中で最も長いパスです.

  • ルートツリーを重み付け幹線として入力すると、ツリーの直径を求めて出力するプログラムが作成されます.以下のツリーが指定されている場合、ツリーの直径は45です.
  • ツリーのノード番号は1~nです.
  • import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
    
    public class Main {
    
        private static class Node {
    
            int num;    // 노드 번호
            int weight; // 가중치
            Node next;  // 다음 형제
    
            public Node(int num, int weight, Node next) {
                this.num = num;
                this.weight = weight;
                this.next = next;
            }
    
        }
    
        private static Node[] adjList;
        private static int result, index;
    
        public static void main(String[] args) throws IOException {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    
            int N = Integer.parseInt(reader.readLine()); // 노드의 개수
            adjList = new Node[N + 1]; // 1-base index
    
            for (int i = 0; i < N - 1; i++) {
                StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
                int from = Integer.parseInt(tokenizer.nextToken());
                int to = Integer.parseInt(tokenizer.nextToken());
                int weight = Integer.parseInt(tokenizer.nextToken());
    
                // 무향 그래프
                adjList[from] = new Node(to, weight, adjList[from]);
                adjList[to] = new Node(from, weight, adjList[to]);
            }
    
            int next = dfs(new boolean[N + 1], 1, 0);
            dfs(new boolean[N + 1], next, 0);
    
            System.out.println(result);
        }
    
        private static int dfs(boolean[] visited, int start, int sum) {
            visited[start] = true;
    
            for (Node node = adjList[start]; node != null; node = node.next) {
                if (!visited[node.num]) {
                    dfs(visited, node.num, sum + node.weight);
                }
            }
    
            if (result < sum) {
                result = sum;
                index = start;
            }
    
            return index;
        }
    
    }
    
  • 日前に解答した木の直径の問題と同じ問題と見てもいい.この問題の違いは重みがあることにある.