Algorithm
[백준] 4386: 별자리 만들기 JAVA
하다보면 되겠지
2023. 2. 26. 21:08
접근
다른 크루스칼 문제들과 핵심 알고리즘은 동일하고, 그 이외의 전처리할 것들이 추가되어 단순히 구현 난이도만 조금 높아진 문제같다.
코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class BJ4386 {
static class Pos{
double x, y;
public Pos(double x, double y) {
this.x = x;
this.y = y;
}
}
static class Edge implements Comparable<Edge> {
int from, to;
double dist;
public Edge(int from, int to, double dist) {
this.from = from;
this.to = to;
this.dist = dist;
}
@Override
public int compareTo(Edge o) {
return (int)(this.dist - o.dist);
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
int n = Integer.parseInt(br.readLine());
ArrayList<Pos> stars = new ArrayList<>();
// 입력값 저장
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
double x = Double.parseDouble(st.nextToken());
double y = Double.parseDouble(st.nextToken());
stars.add(new Pos(x, y));
}
// 별들 간의 거리 계산
PriorityQueue<Edge> pq = addEdge(stars);
double answer = kruskal(n, pq);
System.out.printf("%.2f", answer);
}
static double kruskal(int n, PriorityQueue<Edge> pq){
double res = 0;
int[] root = new int[n];
for (int i = 0; i < n; i++)
root[i] = i;
int cnt = 0;
while(!pq.isEmpty()){
if(cnt == n-1) break;
Edge e = pq.poll();
int r1 = find(root, e.from);
int r2 = find(root, e.to);
if(r1 == r2) continue;
union(r1, r2, root);
res += e.dist;
cnt++;
}
return res;
}
static int find(int[] root, int n){
if(root[n] == n) return n;
return root[n] = find(root, root[n]);
}
static void union(int r1, int r2, int[] root){
root[r1] = r2;
}
private static PriorityQueue<Edge> addEdge(ArrayList<Pos> stars) {
PriorityQueue<Edge> pq = new PriorityQueue<>();
int starCnt = stars.size();
for (int i = 0; i < starCnt; i++) {
for (int j = i+1; j < starCnt; j++) {
double dist = calcDist(stars.get(i), stars.get(j));
pq.add(new Edge(i, j, dist));
}
}
return pq;
}
private static double calcDist(Pos p1, Pos p2) {
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
}
}