https://www.acmicpc.net/problem/2887
dist = MIN(|x1-x2|, |y1-y2|, |z1-z3|)
(10만-1)*3 = 30만
개가 되고 이는 크루스칼 알고리즘을 적용할 수 있다.import java.io.*;
import java.util.*;
public class Main {
public static BufferedReader br;
public static BufferedWriter bw;
public static int N;
public static Point[] X, Y, Z;
public static int[] parent;
//(노드 번호, 좌표값), (노드 번호, 노드 번호)
public static class Point {
int a, b;
public Point(int a, int b) {
this.a = a;
this.b = b;
}
}
//(거리, (a좌표, b좌표))
public static class Planet {
int d;
Point p;
public Planet(int d, Point p) {
this.d = d;
this.p = p;
}
}
//Union-Find
public static int find(int a) {
if (parent[a] == a) return a;
else return parent[a] = find(parent[a]);
}
public static void union(int a, int b) {
a = find(a);
b = find(b);
if (a != b) {
parent[b] = a;
}
}
public static void input() throws IOException {
br = new BufferedReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
N = Integer.parseInt(br.readLine());
X = new Point[N];
Y = new Point[N];
Z = new Point[N];
parent = new int[N];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
X[i] = new Point(i, Integer.parseInt(st.nextToken()));
Y[i] = new Point(i, Integer.parseInt(st.nextToken()));
Z[i] = new Point(i, Integer.parseInt(st.nextToken()));
parent[i] = i;
}
}
public static void solve() throws IOException {
//0. 모든 좌표값들 정렬해주기
Comparator<Point> comp = (p1, p2) -> p1.b - p2.b;
Arrays.sort(X, comp);
Arrays.sort(Y, comp);
Arrays.sort(Z, comp);
//1. 최소 거리 좌표들 모두 후보군에 넣어주기
List<Planet> cands = new ArrayList<>();
for (int i = 0; i < N-1; i++) {
cands.add(new Planet(Math.abs(X[i+1].b - X[i].b), new Point(X[i].a, X[i+1].a)));
cands.add(new Planet(Math.abs(Y[i+1].b - Y[i].b), new Point(Y[i].a, Y[i+1].a)));
cands.add(new Planet(Math.abs(Z[i+1].b - Z[i].b), new Point(Z[i].a, Z[i+1].a)));
}
cands.sort((p1, p2) -> p1.d - p2.d);
//2. 크루스칼 알고리즘 시작
long result = 0;
for (Planet cand : cands) {
if (find(cand.p.a) != find(cand.p.b)) {
union(cand.p.a, cand.p.b);
result += (long) cand.d;
}
}
bw.write(result + "\n");
bw.flush();
}
public static void main(String[] args) throws IOException {
input();
solve();
}
}