static class Edge implements Comparable<Edge>{ int x,y,len;
public Edge(int x, int y, int len) { this.x = x; this.y = y; this.len = len; }
@Override public int compareTo(Edge o) { return Integer.compare(this.len,o.len); } }
int[] f ; //并查集find数组
public int find(int x) { //find函数,判断是否同一个root节点 return f[x] == x ? x : find(f[x]); }
public int minCostConnectPoints(int[][] points) { int h = points.length; f=new int[h+1]; for (int i = 0; i < f.length; i++) {//初始化find数组,让初始每个节点都自成一个集合,互相不联通 f[i]=i; } ArrayList<Edge> edges = new ArrayList<>(); //求边长 for (int i = 0; i < h; i++) { for (int j = i + 1; j < h; j++) { int len = Math.abs(points[i][0] - points[j][0]) + Math.abs(points[i][1] - points[j][1]); if (len != 0) { edges.add(new Edge(i, j, len)); } } } int ans =0; Collections.sort(edges); for(Edge e:edges){ int x=e.x; int y =e.y; int len = e.len; if(find(x)==find(y)) { //如果两个节点是同一个集合中,说明之前已经有其他路径连过了 continue; } ans+=len; f[find(x)] = find(y);//把两集合合并 } return ans; } }
Prim算法
Prim 算法是另一种常见并且好写的最小生成树算法。该算法的基本思想是从一个结点开始,不断加点(而不是 Kruskal 算法的加边)。