SSAFY10-Class5-Algorithm / BOJ

📘SSAFY 10기 5반의 백준 문제 알고리즘 스터디
https://www.acmicpc.net/
5 stars 6 forks source link

[Java] 1967번 트리의 지름 #13

Open peppermintt0504 opened 1 year ago

peppermintt0504 commented 1 year ago

문제 풀이 원본

문제 풀이

해당 문제는 트리의 지름을 구하는 문제로 점과 점 사이가 가장 긴 거리를 구하면 된다. 간단하게 DFS로도 답을 구할 수는 있으나 노드가 많아진다면 시간 초과가 나올 것이다. 그렇기에 최대한 효율적인 방법으로 답을 구해야 한다.


다익스트라 알고리즘과 간단한 이해만 있으면 트리의 지름을 쉽게 구할 수 있다. 트리의 지름을 구하는 법은 아래와 같다.


  1. 임의의 점에서 가장 먼 점을 찾는다.

  2. 해당 점에서 가장 먼 점과의 거리를 구한다. => 트리의 지름


한 점에서 먼 점은 다른 점에서도 멀다는 것을 이해하고 푼다면 쉽게 이해할 수 있다.

2023.07.22 - [algorithm/theory] - 다익스트라(Dijkstra) 알고리즘



풀이 코드

import java.io.*;
import java.util.*;
import java.util.stream.IntStream;

public class Main {
    public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    public static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    public static int INF = 1_000_000;
    public static Map<Integer,ArrayList<Node>> nodes = new HashMap<>();
    public static int T;

    public static class Node implements Comparable<Node>{

        int to;
        int distance;

        public Node() {

        }

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

        @Override
        public int compareTo(Node o) {

            return this.distance - o.distance;
        }

    }

    public static void main(String[] args) throws IOException {

        T = Integer.parseInt(br.readLine());

        if(T == 1) {
            System.out.println(0);
        }else {
            for(int t = 1; t < T; t++) {
                StringTokenizer st =new StringTokenizer(br.readLine());

                int p1 = Integer.parseInt(st.nextToken());
                int p2 = Integer.parseInt(st.nextToken());
                int distance = Integer.parseInt(st.nextToken());

                if(nodes.containsKey(p1)) {
                    nodes.get(p1).add(new Node(p2,distance));
                }else {
                    ArrayList<Node> temp = new ArrayList<>();
                    temp.add(new Node(p2,distance));
                    nodes.put(p1,temp);
                }
                if(nodes.containsKey(p2)) {
                    nodes.get(p2).add(new Node(p1,distance));
                }else {
                    ArrayList<Node> temp = new ArrayList<>();
                    temp.add(new Node(p1,distance));
                    nodes.put(p2,temp);
                }

            }
                int[] first = djikstra(1);
                int max = Arrays.stream(first).reduce(0, (x,v)-> x > v ? x : v);
                int maxIndex = IntStream.range(0, first.length).
                        filter(i -> max == first[i]).
                        findFirst().orElse(-1);
                int[] second = djikstra(maxIndex);
                int answer = Arrays.stream(second).reduce(0, (x,v)-> x > v ? x : v);

                System.out.println(answer);
            bw.flush();
            bw.close();
        }

    }

    public static int[] djikstra(int start) {
        int[] dp = new int[T+1];
        boolean[] visited= new boolean[T+1];
        PriorityQueue<Node> pq = new PriorityQueue<>();

        Arrays.fill(dp, INF);
        dp[0] = 0;
        dp[start] = 0;
        pq.add(new Node(start,0));

        while(!pq.isEmpty()) {
            Node cur = pq.poll();

            if(visited[cur.to]) continue;
            visited[cur.to] = true;

            for(Node next : nodes.get(cur.to)) {
                if(dp[next.to] > dp[cur.to] + next.distance) {
                    dp[next.to] = dp[cur.to] + next.distance;
                    pq.add(new Node(next.to,dp[next.to]));
                }
            }
        }
        return dp;
    }
}