ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [BOJ] 행성 터널
    Algorithm/BOJ 2020. 11. 28. 17:20

    [2887] 행성 터널

    www.acmicpc.net/problem/2887

     

    Solution

    • 행성들을 잇는 최소 간선 트리를 만드는 간단한 문제이다.
    • 처음에는 행성을 이을 수 있는 모든 간선을 미리 구해서 푸는 방식으로 접근했는 데 메모리 초과로 틀렸다.
    • int x, y, z -> 12byte이고,  행성 개수가 최대 10만개이기 때문에 (10만 * 10만 / 2) = 약 50억으로 12byte * 50억이라하면 메모리가 초과될 수 밖에 없었다.
    • 문제를 다시 한 번 살펴보면 행성의 x, y, z 좌표를 각각 비교해서 최소 비용을 구하는 것이므로 모든 행성간의 비용을 계산할 필요 없이 좌표 별로 오름차순으로 정렬한 뒤 바로 옆 행성만 비교하면 된다.
    • 예를들어 행성 A, B, C의 x좌표를 기준으로 정렬한 결과가 B(3) - A(5) - C(9)라고 하면 바로 옆에 있는 행성과의 거리가 가장 적기 때문에 B-A, A-C 만 pq에 저장하면된다.

     

     

    소스코드

     

    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
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.*;
     
    public class Main {
        static int n;
        static int[] p;
        static List<Node> list;
     
        static class Edge implements Comparable<Edge> {
            private int start;
            private int end;
            private int val;
     
            public Edge(int start, int end, int val) {
                this.start = start;
                this.end = end;
                this.val = val;
            }
     
            @Override
            public int compareTo(Edge o) {
                return this.val - o.val;
            }
        }
     
        static class Node {
            private int x;
            private int y;
            private int z;
            private int num;
     
            public Node(int x, int y, int z, int num) {
                this.x = x;
                this.y = y;
                this.z = z;
                this.num = num;
            }
        }
     
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            n = stoi(br.readLine());
     
            p = new int[n];
            for (int i = 0; i < n; i++) {
                p[i] = i;
            }
     
            list = new ArrayList<>();
            int x, y, z;
            StringTokenizer st;
            for (int i = 0; i < n; i++) {
                st = new StringTokenizer(br.readLine());
                x = stoi(st.nextToken());
                y = stoi(st.nextToken());
                z = stoi(st.nextToken());
     
                list.add(new Node(x, y, z, i));
            }
     
            PriorityQueue<Edge> pq = new PriorityQueue<>();
            Collections.sort(list, new Comparator<Node>() {
                @Override
                public int compare(Node o1, Node o2) {
                    return o1.x - o2.x;
                }
            });
            for (int i = 0; i < list.size() - 1; i++) {
                pq.add(new Edge(list.get(i).num, list.get(i + 1).num, Math.abs(list.get(i).x - list.get(i + 1).x)));
            }
     
            Collections.sort(list, new Comparator<Node>() {
                @Override
                public int compare(Node o1, Node o2) {
                    return o1.y - o2.y;
                }
            });
            for (int i = 0; i < list.size() - 1; i++) {
                pq.add(new Edge(list.get(i).num, list.get(i + 1).num,Math.abs(list.get(i).y - list.get(i + 1).y)));
            }
     
            Collections.sort(list, new Comparator<Node>() {
                @Override
                public int compare(Node o1, Node o2) {
                    return o1.z - o2.z;
                }
            });
            for (int i = 0; i < list.size() - 1; i++) {
                pq.add(new Edge(list.get(i).num, list.get(i + 1).num, Math.abs(list.get(i).z - list.get(i + 1).z)));
            }
     
            int answer = 0;
            int count = 0;
            while (!pq.isEmpty()) {
                Edge edge = pq.poll();
                if (find(edge.start) != find(edge.end)) {
                    union(edge.start, edge.end);
                    answer += edge.val;
                    count++;
                }
                if (count == n - 1) {
                    break;
                }
            }
     
            System.out.println(answer);
        }
     
        private static void union(int a, int b) {
            a = find(a);
            b = find(b);
            if (a != b) {
                p[b] = a;
            }
        }
     
        private static int find(int a) {
            if (p[a] == a) {
                return a;
            }
            return p[a] = find(p[a]);
        }
     
        private static int stoi(String s) {
            return Integer.parseInt(s);
        }
    }
    cs

    'Algorithm > BOJ' 카테고리의 다른 글

    [BOJ] 아기상어  (0) 2021.01.12
    [BOJ] 문제집  (0) 2020.11.30
    [BOJ] 진우의 민트초코우유  (0) 2020.11.27
    [BOJ] 인구 이동  (0) 2020.10.28
    [BOJ] 택배  (0) 2020.10.24

    댓글

Designed by Tistory.