ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준]4386: 별자리 만들기 - JAVA
    문제풀이/백준 2021. 4. 26. 19:04

    [백준]4386: 별자리 만들기

    www.acmicpc.net/problem/4386

     

    4386번: 별자리 만들기

    도현이는 우주의 신이다. 이제 도현이는 아무렇게나 널브러져 있는 n개의 별들을 이어서 별자리를 하나 만들 것이다. 별자리의 조건은 다음과 같다. 별자리를 이루는 선은 서로 다른 두 별을 일

    www.acmicpc.net

    풀이

    별들의 좌표를 간선으로 이었을때 최소인 비용을 찾는 문제로 MST알고리즘을 사용하여 풀면 된다.

     

    별을 입력받을때 해당 별의 번호와 좌표를 저장해 주었다.

     

    이 문제에서는 별들이 연결된 간선의 정보가 없으므로 모든 별들 사이의 거리를 직접 구하여 간선list에 저장해 주었다. 그다음 MST알고리즘인 prim, kruskal알고리즘을 사용하여 각각의 MST를 구해주면 된다.

     

    코드

      • prim 알고리즘
    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
    import java.util.*;
     
    public class Main {
        
        static ArrayList<Node> startList = new ArrayList<>();
        static ArrayList<Edge>[] edgeList; 
        static boolean[] visited;
        
        public static void main(String[] args) {
            Scanner scan = new Scanner(System.in);
     
            int n = scan.nextInt();
            edgeList = new ArrayList[n];
            for(int i = 0; i < n; i++) {
                double x = scan.nextDouble();
                double y = scan.nextDouble();
                startList.add(new Node(i, x, y));
                edgeList[i] = new ArrayList<>();
            }
            
            //모든 간선 계산
            for(int i = 0; i < n; i++) {
                for(int j = i + 1; j < n; j++) {
                    double dist = Math.sqrt(Math.pow(startList.get(i).x - startList.get(j).x, 2+ Math.pow(startList.get(i).y - startList.get(j).y, 2));
                    edgeList[i].add(new Edge(j, dist));
                    edgeList[j].add(new Edge(i, dist));
                }
            }
            
            visited = new boolean[startList.size()];
            double result = prim();
            System.out.printf("%.2f", result);
        }
        
        public static double prim() {
            PriorityQueue<Edge> q = new PriorityQueue<>();
            q.offer(new Edge(00));
            double dist = 0;
            
            while(!q.isEmpty()) {
                Edge current = q.poll();
                
                if(visited[current.end] == false) {
                    dist += current.cost;
                    visited[current.end] = true;
                }
                else continue;        
                
                for(int i = 0; i < edgeList[current.end].size(); i++) {
                    Edge next = edgeList[current.end].get(i);
                    if(visited[next.end] == false) q.offer(new Edge(next.end, next.cost));
                }
            }
            return dist;
        }
        
        public static class Node {
            int num;
            double x;
            double y;
            
            public Node(int num, double x, double y) {
                this.num = num;
                this.x = x;
                this.y = y;
            }
        }
        
        public static class Edge implements Comparable<Edge> {
            int end;
            double cost;
            
            public Edge(int end, double cost) {
                this.end = end;
                this.cost = cost;
            }
            
            @Override
            public int compareTo(Edge e) {
                if(this.cost < e.cost) return -1;
                return 1;
            }
        }
    }
     
    cs

     

      • kruskal 알고리즘
    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
    import java.util.*;
     
    public class Main {
        
        static ArrayList<Node> startList = new ArrayList<>();
        static ArrayList<Edge> edgeList = new ArrayList<>(); 
        static int[] parent;
        static PriorityQueue<Edge> q = new PriorityQueue<>();
        
        public static void main(String[] args) {
            Scanner scan = new Scanner(System.in);
     
            int n = scan.nextInt();
            for(int i = 0; i < n; i++) {
                double x = scan.nextDouble();
                double y = scan.nextDouble();
                startList.add(new Node(i, x, y));
            }
            
            //모든 간선 계산
            for(int i = 0; i < n; i++) {
                for(int j = i + 1; j < n; j++) {
                    double dist = Math.sqrt(Math.pow(startList.get(i).x - startList.get(j).x, 2+ Math.pow(startList.get(i).y - startList.get(j).y, 2));
                    q.add(new Edge(i, j, dist));
                }
            }
            
            parent = new int[startList.size()];
            double result = kruskal();
            System.out.printf("%.2f", result);
        }
        
        public static double kruskal() {
            for(int i = 0; i < startList.size(); i++) {
                parent[i] = i;
            }
            
            double dist = 0;
            while(!q.isEmpty()) {
                Edge current = q.poll();
                
                int p1 = find(current.start);
                int p2 = find(current.end);
                
                if(p1 != p2) {
                    union(p1, p2);
                    dist += current.cost;
                }
            }
            return dist;
        }
        
        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 {
            int num;
            double x;
            double y;
            
            public Node(int num, double x, double y) {
                this.num = num;
                this.x = x;
                this.y = y;
            }
        }
        
        public static class Edge implements Comparable<Edge> {
            int start;
            int end;
            double cost;
            
            public Edge(int start, int end, double cost) {
                this.start = start;
                this.end = end;
                this.cost = cost;
            }
            
            @Override
            public int compareTo(Edge e) {
                if(this.cost < e.cost) return -1;
                return 1;
            }
        }
    }
    cs

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

    [백준]1202: 보석 도둑 - JAVA  (1) 2021.04.27
    [백준]1655: 가운데를 말해요 - JAVA  (0) 2021.04.27
    [백준]2096: 내려가기 - JAVA  (0) 2021.04.26
    [백준]15686: 치킨 배달 - JAVA  (0) 2021.04.25
    [백준]1062: 가르침 - JAVA  (0) 2021.04.24

    댓글

Designed by Tistory.