N개의 필드 존재 (1 ≤ N ≤ 2000)
각 필드는 2차원 평면상 (xi, yi)로 표시(0≤ xi, yi ≤ 1000)
$$ i,j 필드 사이 비용 = (x_i-x_j)^2 + (y_i-y_j)^2 $$
모든 필드를 최소비용으로 연결하고 싶다.
그런데 비용이 C 이상인 파이프만 설치할 수 있다. (1≤ C≤ 1,000,000)
크루스칼 알고리즘을 사용하면 될 것 같다.
- 주어진 정보로 간선을 계산해 저장한다.
- 비용이 작은 간선부터 꺼내 두 노드를 연결한다.
- 노드 연결 시 이미 같은 집합이거나 비용이 C보다 작다면 연결하지 않는다.
package boj;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class BOJ10021 {
static class Edge {
int from;
int to;
int cost;
public Edge(int from, int to, int cost) {
this.from = from;
this.to = to;
this.cost = cost;
}
@Override
public String toString() {
return from + "," + to + "," + cost;
}
}
static FastReader scan = new FastReader();
static int N, C;
static int[][] fields;
static List<Edge>[] graph;
static void input() {
N = scan.nextInt();
C = scan.nextInt();
fields = new int[N][2];
for (int i = 0; i < N; i++) {
fields[i] = new int[]{scan.nextInt(), scan.nextInt()};
}
}
static void initGraph() {
graph = new ArrayList[N];
for (int i = 0; i < N; i++) {
graph[i] = new ArrayList<>();
}
// 각 노드부터 출발한 거리 계산
for (int i = 0; i < N; i++) {
int[] from = fields[i];
for (int j = i + 1; j < N; j++) {
int[] to = fields[j];
int cost = calcCost(from, to);
graph[i].add(new Edge(i, j, cost));
}
}
}
static int calcCost(int[] from, int[] to) {
return (int) (Math.pow((from[0] - to[0]), 2) + Math.pow((from[1] - to[1]), 2));
}
static void solve() {
int totalCost = 0;
int edgeCount = 0;
PriorityQueue<Edge> pq = new PriorityQueue<>(Comparator.comparingInt(e -> e.cost));
for (int i = 0; i < N; i++) {
for (Edge e : graph[i]) {
if (e.cost < C) continue;
pq.add(e);
}
}
int[] parent = new int[N];
for (int i = 0; i < N; i++) {
parent[i] = i;
}
while (!pq.isEmpty()) {
Edge curr = pq.poll();
int from = curr.from;
int to = curr.to;
int cost = curr.cost;
if (isConnected(parent, from, to)) {
continue;
}
union(parent, from, to);
totalCost += cost;
edgeCount++;
}
System.out.println(edgeCount == N - 1 ? totalCost : -1);
}
static boolean isConnected(int[] parent, int x, int y) {
return find(parent, x) == find(parent, y);
}
static void union(int[] parent, int x, int y) {
int rootX = find(parent, x);
int rootY = find(parent, y);
if (rootX < rootY) {
parent[rootY] = rootX;
} else {
parent[rootX] = rootY;
}
}
static int find(int[] parent, int x) {
if (parent[x] != x) {
parent[x] = find(parent, parent[x]);
}
return parent[x];
}
public static void main(String[] args) {
input();
initGraph();
solve();
}
static class FastReader {
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
String next() {
while (st == null || !st.hasMoreTokens()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
}
}
'Algorithm > BOJ' 카테고리의 다른 글
BOJ 11049 - 행렬 곱셈 순서 (1) | 2024.11.09 |
---|---|
BOJ 6087 - 레이저 통신 (0) | 2024.11.07 |
BOJ 2292 - 벌집 (5) | 2024.11.06 |
BOJ 2933 - 미네랄 (0) | 2024.11.05 |
BOJ 15591 - MooTube (Silver) (0) | 2024.10.31 |