[백준, BOJ 1774] 우주신과의 교감 (java)
Problem Solving/BOJ

[백준, BOJ 1774] 우주신과의 교감 (java)

728x90

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

 

1774번: 우주신과의 교감

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

www.acmicpc.net

728x90

메모리: 49,552 KB , 시간: 732 ms

사용 알고리즘: 그래프 이론, 스패닝 트리, 크루스칼 알고리즘

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

    static int[] parent;

    public static void main(String[] args) throws Exception{

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        // N := 우주신들의 개수, M := 통로의 개수
        st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        // 우주신들 좌표 정보
        int[][] map = new int[N + 1][2];

        //황선자와 우주신들의 좌표 입력
        int x, y;
        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine());
            map[i][0] = Integer.parseInt(st.nextToken());
            map[i][1] = Integer.parseInt(st.nextToken());
        }

        // 크루스칼 알고리즘을 사용하기 위한 부모 정보 배열
        parent = new int[N + 1];
        for (int i = 1; i <= N; i++) {
            parent[i] = i;
        }

        // 이미 연결된 곳 parent 배열에 연결해주기
        int a, b;
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            a = Integer.parseInt(st.nextToken());
            b = Integer.parseInt(st.nextToken());
            union(a, b);
        }

        // 크루스칼 알고리즘을 위해 모든 우주신 간 거리 구하기
        ArrayList<double[]> list = new ArrayList<>();
        for (int i = 1; i < N; i++) {
            for (int j = i + 1; j <= N; j++) {
                list.add(new double[] {i, j, Math.sqrt(Math.pow(map[i][0] - map[j][0], 2) + Math.pow(map[i][1] - map[j][1], 2))});
            }
        }

        // 간선 길이 오름차순 정렬
        Collections.sort(list, (o1, o2) -> o1[2] < o2[2] ? -1 : 1);

        double result = 0; // 간선을 새로 연결하는 경우, 간선 길이를 더해줌
        for (int i = 0; i < list.size(); i++) {
            if(union((int)list.get(i)[0], (int)list.get(i)[1])) {
                result += list.get(i)[2];
            }
        }

        System.out.println(String.format("%.2f", result));
    }

    private static int find(int a) {
        if(parent[a] == a) return a;

        return parent[a] = find(parent[a]);
    }

    private static boolean union(int a, int b) {
        a = find(a);
        b = find(b);

        if(a == b) return false; // 이미 연결 되어 있음

        if(a < b) parent[b] = a;
        else parent[a] = b;
        return true; // 새로 연결함
    }
}
728x90