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

풀이 ) MST - Kruskal
입력으로 들어온 모든 점을 저장한 후 두 점 사이의 거리를 모두 구해서 최소힙에 넣어준다.
이후 m개의 입력으로 들어온 선분을 먼저 이어주고 크루스칼 알고리즘을 적용하여 MST를 구했다.
코드 )
import java.io.*;
import java.util.*;
class Main {
static int n, m;
static Point[] points;
static PriorityQueue<Node> pq;
static int[] root;
static int nPick = 1;
public static void main(String[] args) throws IOException {
input();
kruskal();
}
static void kruskal() {
double answer = 0;
while(!pq.isEmpty()) {
if(nPick == n) {
break;
}
Node cur = pq.poll();
if(find(cur.v1) != find(cur.v2)) {
answer += cur.w;
nPick++;
union(cur.v1, cur.v2);
}
}
System.out.printf("%.2f\n", answer);
}
static void input() 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());
root = new int[n];
points = new Point[n];
for(int i = 0; i < n; ++i) {
root[i] = i;
st = new StringTokenizer(br.readLine(), " ");
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
points[i] = new Point(x, y);
}
// MinHeap
pq = new PriorityQueue<>((o1, o2) ->
Double.compare(o1.w, o2.w)
);
for(int i = 0; i < n-1; ++i) {
for(int j = i+1; j < n; ++j) {
int dx = points[i].x-points[j].x, dy = points[i].y-points[j].y;
double tmp = Math.sqrt(1L*dx*dx+1L*dy*dy); // long casting
pq.offer(new Node(i, j, tmp));
}
}
for(int i = 0; i < m; ++i) {
st = new StringTokenizer(br.readLine(), " ");
int v1 = Integer.parseInt(st.nextToken())-1;
int v2 = Integer.parseInt(st.nextToken())-1;
if(find(v1) != find(v2)) {
nPick++;
union(v1, v2);
}
}
}
static void union(int v1, int v2) {
int root1 = find(v1);
int root2 = find(v2);
if(v1 < v2) {
root[root2] = root1;
} else {
root[root1] = root2;
}
}
static int find(int v) {
if(root[v] == v) {
return v;
}
return root[v] = find(root[v]);
}
static class Node {
int v1, v2;
double w;
public Node(int v1, int v2, double w) {
this.v1 = v1;
this.v2 = v2;
this.w = w;
}
}
static class Point {
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
}
주의 )
두 점 사이의 거리를 구할 때, 좌표의 범위가 [0, 1000000] 여서 차이를 제곱하면 Integer 범위를 벗어나기 때문에 Long으로 캐스팅해주는 작업이 필요하다.
반응형
'문제풀이 > 백준' 카테고리의 다른 글
[JAVA] 백준 - 11286 : 절댓값 힙 (0) | 2023.05.28 |
---|---|
[JAVA] 백준 - 16236 : 아기상어 (0) | 2021.09.04 |
[JAVA] 백준 - 16947 : 서울 지하철 2호선 (0) | 2021.08.31 |
[JAVA] 백준 - 17612 : 쇼핑몰 (0) | 2021.04.02 |
[JAVA] 백준 - 2263 : 트리의 순회 (0) | 2021.02.28 |