package com.heu.wsq.leetcode.bingchaji;
import java.util.*;
public class MinCostConnectPoints {
public int minCostConnectPoints(int[][] points){
int n = points.length;
UnionFind unionFind = new UnionFind(n);
List<Edge> list = new ArrayList<>();
for (int i = 0; i < n; i++){
for (int j = i + 1; j < n; j++){
list.add(new Edge(dist(points, i, j), i, j));
}
}
Collections.sort(list, new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
return o1.len - o2.len;
}
});
int ret = 0, num = 1;
for (Edge edge : list) {
int len = edge.len, x = edge.x, y = edge.y;
if (!unionFind.isConnected(x, y)){
unionFind.union(x, y);
ret += len;
num++;
if (num == n){
break;
}
}
}
return ret;
}
private int dist(int[][] points, int i, int j) {
return Math.abs(points[i][0] - points[j][0]) + Math.abs(points[i][1] - points[j][1]);
}
private class UnionFind{
private int[] parent;
private int[] rank;
private int n;
public UnionFind(int n){
this.n = n;
this.rank = new int[n];
this.parent = new int[n];
Arrays.fill(rank, 1);
for (int i = 0; i < n; i++) {
this.parent[i] = i;
}
}
public int find(int x){
if (x != parent[x]){
parent[x] = find(parent[x]);
}
return parent[x];
}
public void union(int x, int y){
int rootX = find(x);
int rootY = find(y);
if (rootX == rootY){
return;
}
if (rank[rootX] < rank[rootY]){
int tmp = rootX;
rootX = rootY;
rootY = tmp;
}
rank[rootX] += rank[rootY];
parent[rootY] = parent[rootX];
}
public boolean isConnected(int x, int y){
return find(x) == find(y);
}
}
}
class Edge{
int x;
int y;
int len;
public Edge(int len, int x, int y){
this.x = x;
this.y = y;
this.len = len;
}
}