- 连接所有点的最小费用
问题拆解:size个顶点求最小生成树(无向图)
思路:
先模拟,将所有边加入到edges 中,按照weight权值排序(从小到大),之后依次遍历已排序的边,加入该边,判断是否与当前的图结构成环(并查集判环),否则加入该边,是则continue,直到加入了size-1条边为止跳出循环
class Solution {
public int minCostConnectPoints(int[][] points) {
int size = points.length; //size个点,抽象为各个点,下标为0开始
LinkedList<Node> edges = new LinkedList<>();
for(int i=0;i<size;i++){
for(int j=i+1;j<size;j++){ //后面的点
//存储所有的边信息
edges.add(new Node(i,j,dist(points,i,j))); //size个顶点 (size-1+1)*(size-1)个边
}
}
Collections.sort(edges, new Comparator<Node>() {
public int compare(Node n1, Node n2) {
return n1.weight - n2.weight; //从小到大
}
});
int res = 0;
int len = 1;
Union union = new Union(size);
for(Node node:edges){
if(union.connect(node.begin,node.end)){
res+=node.weight;
len++;
if(len==size){
break;
}
}
}
return res;
}
//第a个点和第b个点的曼哈顿距离
public int dist(int[][] points,int a,int b){
int[] aa = points[a]; //当前的点
int[] bb = points[b]; //后面的点
return Math.abs(aa[0] - bb[0]) + Math.abs(aa[1] - bb[1]);
}
}
//并查集去环
class Union{
int[] parent;
int[] ranks;
public Union(int n){
parent = new int[n];
ranks = new int[n];
for(int i=0;i<n;i++){
parent[i] = i; //自己指向自己
ranks[i] = 1; //ranks高度为1
}
}
public boolean connect(int a,int b){
int p1 = find(a);
int p2 = find(b);
if(p1==p2){
return false;
}
if(ranks[p1]>ranks[p2]){
parent[p2] = parent[p1];
}else if(ranks[p1]<ranks[p2]){
parent[p1] = parent[p2];
}else{
parent[p1] = parent[p2];
ranks[p2] +=1;
}
return true;
}
public int find(int v){
if(v != parent[v]){
parent[v] = find(parent[v]);
}
return parent[v];
}
}
//所有边的信息
class Node{
int begin; //第begin个顶点
int end; //第end个顶点
int weight;
public Node(int begin,int end,int weight){
this.begin = begin;
this.end = end;
this.weight = weight;
}
}