๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ”Ž Algorithm/๐Ÿ’ป ๋ฌธ์ œ ํ’€์ด

[๋ฐฑ์ค€] 1967. ํŠธ๋ฆฌ์˜ ์ง€๋ฆ„

by Seongpyo Hong 2021. 3. 6.

๋ฌธ์ œ

 

ํ’€์ด

์ฒ˜์Œ ์‹œ๋„ํ–ˆ๋˜ ๋ฐฉ๋ฒ•์€ 1๋ฒˆ์˜ ์ž์‹๋…ธ๋“œ๋“ค์„ ์‹œ์ž‘์ ์œผ๋กœ ์žก์•„ DFS๋ฅผ ํ†ตํ•ด ํƒ์ƒ‰ํ•˜๋ฉด์„œ ์™ผ์ชฝ ์ž์‹๊ณผ์˜ ๊ฑฐ๋ฆฌ, ์˜ค๋ฅธ์ชฝ ์ž์‹๊ณผ์˜ ๊ฑฐ๋ฆฌ, ๋ถ€๋ชจ์™€์˜ ๊ฑฐ๋ฆฌ ์ค‘์— ์ƒ์œ„ 2๊ฐœ์˜ ๊ฐ’์„ ๊ณจ๋ผ ์ตœ๋Œ€๊ฐ’์„ ๊ฐฑ์‹ ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์ง„ํ–‰ํ•˜์˜€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์ตœ๋Œ€๊ฐ’์ด 1๋ฒˆ์˜ ๋‹ค๋ฅธ ์ค„๊ธฐ์™€ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€(notCompleted), ์•„๋‹ˆ๋ฉด ์ด๋ฏธ ์™„์„ฑ๋œ ์ง€๋ฆ„์ธ์ง€(completed) ํŒ๋ณ„ํ•˜๋Š” flag๋ฅผ ํ†ตํ•ด ์ตœ๋Œ€ ์ง€๋ฆ„์„ ๊ตฌํ•˜๋ ค๊ณ  ํ–ˆ๋‹ค.

์ด ๋ฐฉ๋ฒ•์ด ์ž˜๋ชป๋œ ์ด์œ ๋Š” ๋จผ์ € ๋ฌธ์ œ์—์„œ ์ด์ง„ ํŠธ๋ฆฌ๋ผ๋Š” ์กฐ๊ฑด์ด ์—†๋Š”๋ฐ ์ด์ง„ํŠธ๋ฆฌ๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ํ’€์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๊ณ , ๋˜ํ•œ ์œ„์˜ ๊ทธ๋ž˜ํ”„์—์„œ 
4-7 : 100 / 4-8 : 100์œผ๋กœ ์ˆ˜์ •ํ•œ ๊ฒฝ์šฐ ์™ผ์ชฝ ์ค„๊ธฐ์˜ ์ตœ๋Œ€๊ฐ’์ด 200์ด ๋‚˜์™€์•ผํ•˜๋Š”๋ฐ 4์˜ ๋ถ€๋ชจ๋…ธ๋“œ์ธ 2๊ฐ€ ์ž์‹์ด ํ•˜๋‚˜๋ฐ–์— ์—†๊ธฐ ๋•Œ๋ฌธ์— 200 + 5๋กœ ๊ฐฑ์‹ ๋˜๋Š” ๋ฌธ์ œ์ ์ด ์กด์žฌํ•œ๋‹ค.

ํ‹€๋ฆฐ ํ’€์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. (์‚ฌ์‹ค ํ’€๋ฉด์„œ๋„ ์ผ๋ฐ˜ํ™”์‹œํ‚ค์ง€ ๋ชปํ•œ ์กฐ๊ฑด์ด ๋„ˆ๋ฌด ๋งŽ์•„ ์ž˜๋ชป๋œ ๋ฐฉ๋ฒ•์ธ ๊ฒƒ ๊ฐ™์•˜์ง€๋งŒ ๋…ผ๋ฆฌ์ƒ ๋ฌธ์ œ๋ฅผ ์ฐพ์ง€ ๋ชปํ•ด์„œ ๊ทธ๋Œ€๋กœ ์ง„ํ–‰ํ–ˆ์—ˆ๋‹ค.)

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

public class Solution1967 {
    static class Node {
        int dest;
        int weight;

        public Node(int dest, int weight) {
            this.dest = dest;
            this.weight = weight;
        }
    }
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static int N, maxLength;
    static boolean isCompleted;
    static ArrayList<Node>[] nodes;
    public static void main(String[] args) throws IOException {
        N = Integer.parseInt(br.readLine());
        nodes = new ArrayList[N+1];

        for (int i = 0; i < N-1; i++) {
            String[] line = br.readLine().split(" ");
            int idx = Integer.parseInt(line[0]);
            if (nodes[idx] == null)
                nodes[idx] = new ArrayList<>();
            nodes[idx].add(new Node(Integer.parseInt(line[1]), Integer.parseInt(line[2])));
        }

        if (N == 1) {
            System.out.println(0);
            return;
        }

        ArrayList<Integer> completed = new ArrayList<>();
        ArrayList<Integer> notCompleted = new ArrayList<>();
        for(Node n : nodes[1]) {
            isCompleted = false;
            int len = dfs(n.dest, n.weight);
            if (!isCompleted)
                notCompleted.add(len);
            else
                completed.add(len);
        }

        completed.sort(Integer::compareTo);
        notCompleted.sort(Integer::compareTo);

        System.out.println(completed);
        System.out.println(notCompleted);
        int maxCompleted = 0, maxNotCompleted = 0;
        if (completed.size() > 0)
            maxCompleted = completed.get(completed.size() - 1);
        if (notCompleted.size() > 0)
            maxNotCompleted = notCompleted.get(notCompleted.size() - 1);

        if (notCompleted.size() < 2)
            System.out.println(Math.max(maxCompleted, maxNotCompleted));
        else {
            int secondNotCompleted = notCompleted.get(notCompleted.size() - 2);
            System.out.println(Math.max(maxCompleted, maxNotCompleted + secondNotCompleted));
        }
    }

    private static int dfs(int idx, int len) {
        if (nodes[idx] == null)
            return len;

        int[] max = new int[2];
        for (Node n : nodes[idx]) {
            int curLen = dfs(n.dest, n.weight);
            if (max[1] == 0)
                max[1] = curLen;
            else if (max[0] < curLen)
                max[0] = curLen;
            else if (max[1] < curLen)
                max[1] = curLen;
        }
        if (max[0] > len && max[1] > len)
            isCompleted = true;
        else if (isCompleted )
            return max[0] + max[1];
    }
}

๊ทธ๋ž˜์„œ ๋‹ค์Œ์œผ๋กœ ์ƒ๊ฐํ–ˆ๋˜ ๋ฐฉ๋ฒ•์€ ๋จผ์ € 1๋ฒˆ ๋…ธ๋“œ์—์„œ dfs๋ฅผ ์ง„ํ–‰ํ•ด์„œ ๊ฐ€์žฅ ๋จผ ์ (restartIdx)๋ฅผ ์ฐพ๊ณ  ์ด ์ ์—์„œ ๋‹ค์‹œ ๊ฐ€์žฅ ๋จผ ์ ์„ ์ฐพ์•„ ํŠธ๋ฆฌ์˜ ์ตœ๋Œ€ ์ง€๋ฆ„์„  ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด์—ˆ๋‹ค.

์ด ๋ฐฉ๋ฒ•์„ ์œ„ํ•ด์„œ๋Š” ๋ฌธ์ œ์—์„œ ๋‹จ๋ฐฉํ–ฅ์ด๋ผ๊ณ  ๋งํ–ˆ์ง€๋งŒ ์–‘๋ฐฉํ–ฅ์œผ๋กœ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•˜๊ณ  ์ฒซ ๋ฒˆ์งธ๋กœ ์ƒ๊ฐํ–ˆ๋˜ ๋ฐฉ๋ฒ•์€ ์ธ์ ‘ํ–‰๋ ฌ์„ ํ†ตํ•ด ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ธ์ ‘ ํ–‰๋ ฌ์˜ ๊ฒฝ์šฐ ์ตœ๋Œ€ 10000 * 10000 ๊ฐœ์˜ ๋ฐฐ์—ด์ด ๋งŒ๋“ค์–ด์ง€๊ณ  ์ด๋กœ ์ธํ•ด ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค.

๋‘ ๋ฒˆ์งธ๋กœ ์„ ํƒํ•œ ๋ฐฉ๋ฒ•์€ ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ src-dest : weight์˜ ๊ด€๊ณ„์— ์žˆ๋‹ค๋ฉด map[src]์— dest์— ์ •๋ณด๋ฅผ, map[dest]์— src์˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰ํ•˜์˜€๊ณ  ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์ตœ์ข… ํ’€์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

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

public class Solution1967 {
    static class Node {
        int idx;
        int weight;

        public Node(int idx, int dist) {
            this.idx = idx;
            this.weight = dist;
        }
    }
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static int N, maxLength, restartIdx;
    static ArrayList<Node>[] nodes;
    static boolean[] visited;
    public static void main(String[] args) throws IOException {
        N = Integer.parseInt(br.readLine());
        nodes = new ArrayList[N+1];
        for (int i = 0; i < N-1; i++) {
            String[] line = br.readLine().split(" ");
            int src = Integer.parseInt(line[0]);
            int dest = Integer.parseInt(line[1]);
            int weight =Integer.parseInt(line[2]);
            if (nodes[src] == null)
                nodes[src] = new ArrayList<>();
            if (nodes[dest] == null)
                nodes[dest] = new ArrayList<>();
            nodes[src].add(new Node(dest, weight));
            nodes[dest].add(new Node(src, weight));

        }

        if (N == 1) {
            System.out.println(0);
            return;
        }
        visited = new boolean[N+1];
        dfs(1, 0);

        maxLength = 0;
        visited = new boolean[N+1];
        dfs(restartIdx, 0);
        System.out.println(maxLength);
    }

    private static void dfs(int src, int weight) {
        if (visited[src]) return;
        visited[src] = true;

        if (maxLength < weight) {
            maxLength = weight;
            restartIdx = src;
        }

        for (int i = 0; i < nodes[src].size(); i++) {
            if (visited[nodes[src].get(i).idx]) continue;

            dfs(nodes[src].get(i).idx, weight + nodes[src].get(i).weight);
        }
    }
}

๋Œ“๊ธ€