알고리즘/알고리즘문풀

BOJ - 우주신과의 교감 1774번 (JAVA)

developer-ellen 2022. 9. 10. 20:22

❓ 문제 - 백준 우주신과의 교감 1774번 - JAVA 풀이법

 

출처 

(https://www.acmicpc.net/problem/1774)

 

1774번: 우주신과의 교감

(1,1) (3,1) (2,3) (4,3) 이렇게 우주신들과 황선자씨의 좌표가 주어졌고 1번하고 4번이 연결되어 있다. 그렇다면 1번하고 2번을 잇는 통로를 만들고 3번하고 4번을 잇는 통로를 만들면 신들과 선자씨끼

www.acmicpc.net

 

 

📝 문제해결법

1. 문제

  • n개의 우주신의 정보(x, y)가 주어질 때 이미 연결된 신들을 제외한 다른 우주신을 최소 비용으로 해서 모두 다 연결할 때의 통로 길이 합을 구하여라.

 

2. 해결 방법

  • MST(최소 스패닝 트리)로 우선 각 우주신들의 모두 연결된 경우를 union_find 해준다.
  • 그리고 나머지 각 우주신들은 다 연결되어 있으므로 거리를 pq(우선순위큐)에 넣어 최소 거리부터 union_find를 해줘서 모든 우주신들을 최소비용으로 연결할 수 있도록 구현해준다.

 

3. 느낀점

  • 계속 9%에서 틀렸다고 해서 진짜 int가 아닌 long을 쓸 부분이 있는지, 아니면 코드 자체를 잘못 구현했는지를 계속 살폈는데 알고보니 통로의 길이는 소숫점 둘째자리로 처리되어 해야 해서 Math.pow(~, 2) 이런 식으로 거듭제곱을 처리해야했음..

 

 

 

💻 소스코드 (JAVA)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main_1774 {
    public static int[] parent;
    public static Node[] node;

    public static class Node {
        int x;
        int y;
        public Node(int x, int y){
            this.x = x;
            this.y = y;
        }
    }

    public static class Edge implements Comparable<Edge> {
        int a;
        int b;
        double dist;
        public Edge(int a, int b, double dist){
            this.a = a;
            this.b = b;
            this.dist = dist;
        }

        @Override
        public int compareTo(Edge o) {
            return Double.compare(this.dist, o.dist);
        }
    }

    public static int n, m;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());

        node = new Node[n+1];
        parent = new int[n+1];
        for(int i=0;i<n;i++){
            st = new StringTokenizer(br.readLine(), " ");
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            node[i+1] = new Node(x, y);
            parent[i+1] = i+1;
        }

        for(int i=0;i<m;i++){
            st = new StringTokenizer(br.readLine()," ");
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            union_parent(a, b);
        }

        PriorityQueue<Edge> pq = new PriorityQueue<>();
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                double cost = Math.sqrt(Math.pow(node[i].x - node[j].x, 2) + Math.pow(node[i].y - node[j].y, 2));

                pq.add(new Edge(i, j, cost));
            }
        }

        double cost = 0;
        while (!pq.isEmpty()){
            Edge edge = pq.poll();
            if(find_parent(edge.a) != find_parent(edge.b)){
                union_parent(edge.a, edge.b);
                cost += edge.dist;
            }
        }


        System.out.printf("%.2f", cost);


    }

    public static int find_parent(int x) {
        if(parent[x] == x) return x;
        return parent[x] = find_parent(parent[x]);
    }

    public static void union_parent(int a, int b){
        a = find_parent(a);
        b = find_parent(b);
        if(a < b){
            parent[b] = a;
        } else {
            parent[a] = b;
        }
    }
}