ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준]20010: 악덕 영주 혜유 - JAVA
    문제풀이/백준 2021. 7. 7. 17:08

    [백준]20010: 악덕 영주 혜유

     

    20010번: 악덕 영주 혜유

    FT온라인 게임에서 치열한 경쟁을 통해 영주가 된 혜유는 퀘스트를 받았다. 퀘스트의 내용은 자신이 관리하고 있는 마을 사이에 교역로를 건설하여 마을 간 교류를 활성화시키는 것이다. 이때,

    www.acmicpc.net

    풀이

    🪑 MST를 구하는 활용문제이다.

     

    문제의 조건들을 정리해보자.

    • 마을간 교역로는 양방향이다.
    • 모든 마을은 연결되어있다.
    • 구하는 값은 MST 비용과 MST 내에서 가장 먼 노드간의 거리이다.

     

    🔧 이제 문제 풀이 과정을 생각해 보자.

    1. 마을 간 교역로 정보를 입력 받은 후 MST를 구한다. 
    2. MST를 저장해 둔 다음 MST를 내에서 DFS로 가장 먼 노드간의 거리를 구한다.
    3. 가장 먼 노드간의 거리를 구하기 위해선 먼저, 한 정점에서 가장 먼 노드를 구한 다음 그 정점에서 다시 가장 먼 노드를 구하면 된다. (백준 1167: 트리의 지름 참고)

     

    🔹 MST를 구한다.

    - MST알고리즘은 대표적으로 prim, kruskal이 있다. 나는 최소 간선 트리로 선택된 간선의 정보를 저장해 주기 위해 kruskal 알고리즘을 사용하였다. 

     

    🔹 DFS로 가장 먼 노드간의 거리를 구한다.

    - MST로 선택된 간선들의 정보를 가지고 DFS 탐색을 진행한다.

    - 가장 먼 노드 사이의 거리를 구하는 방법은 먼저 한 정점에서 가장 먼 노드를 구한 다음, 그 정점에서 다시 가장 먼 노드까지의 거리를 구하면 된다. (백준 1167: 트리의 지름 참고)

    - 해당 방법으로 가장 먼 노드간의 거리를 구해주면 된다.

     

    코드

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    import java.util.*;
     
    public class Main {
     
        static PriorityQueue<Node> q = new PriorityQueue<>();
        static ArrayList<Node>[] MST;
        static int[] parent;
        static int n, k;
        static boolean[] visited;
        static int max;
        static int startNode;
     
        public static void main(String[] args) {
            Scanner scan = new Scanner(System.in);
            
            n = scan.nextInt();
            k = scan.nextInt();
     
            MST = new ArrayList[n]; //최소 간선 트리 정보를 저장하는 리스트
            for(int i = 0; i < n; i++) {
                MST[i] = new ArrayList<>();
            }
     
            for(int i = 0; i < k; i++) {
                int s = scan.nextInt();
                int e = scan.nextInt();
                int cost = scan.nextInt();
                q.offer(new Node(s, e, cost));
            }
            int min = kruskal(); //MST 비용을 구한다.
           
            max = Integer.MIN_VALUE;
            visited = new boolean[n];
            visited[0= true;
            dfs(00);
     
            max = Integer.MIN_VALUE;
            visited = new boolean[n];
            visited[startNode] = true;
            dfs(startNode, 0);
     
            System.out.println(min);
            System.out.println(max);
        }
     
        public static void dfs(int node, int total) {
            if(max < total) {
                max = total;
                startNode = node;
            }
     
            for(int i = 0; i < MST[node].size(); i++) {
                Node next = MST[node].get(i);
                if(!visited[next.e]) {
                    visited[next.e] = true;
                    dfs(next.e, total + next.cost);
                }
            }
        } 
     
        public static int kruskal() {
            parent = new int[n];
            for(int i = 0; i < n; i++) {
                parent[i] = i;
            }
     
            int min = 0;
            while(!q.isEmpty()) {
                Node current = q.poll();
     
                int p1 = find(current.s);
                int p2 = find(current.e);
     
                if(p1 != p2) {
                    union(p1, p2);
                    MST[current.s].add(new Node(current.e, current.cost));
                    MST[current.e].add(new Node(current.s, current.cost));
                    min += current.cost;
                }
            }
            return min;
        }
     
        public static int find(int a) {
            if(parent[a] == a) return a;
            else return parent[a] = find(parent[a]);
        }
     
        public static void union(int a, int b) {
            parent[a] = b;
        }
     
        public static class Node implements Comparable<Node> {
            int s;
            int e;
            int cost;
     
            public Node(int s, int e, int cost) {
                this.s = s;
                this.e = e;
                this.cost = cost;
            }
     
            public Node(int e, int cost) {
                this.e = e;
                this.cost = cost;
            }
     
            @Override
            public int compareTo(Node n) {
                return this.cost - n.cost;
            }
        }
    }
    cs

    '문제풀이 > 백준' 카테고리의 다른 글

    [백준]20444: 색종이와 가위 - JAVA  (0) 2021.07.14
    [백준]5710: 전기 요금 - JAVA  (0) 2021.07.13
    [백준]13392: 구간 나누기2 - JAVA  (1) 2021.07.06
    [백준]1042: 거짓말 - JAVA  (0) 2021.07.05
    [백준]14890: 경사로 - JAVA  (0) 2021.07.03

    댓글

Designed by Tistory.