题目地址:
https://leetcode.com/problems/connecting-cities-with-minimum-cost/
给定一个带权无向图,图由给定一系列的边的方式给出。求其最小生成树的权和。如果不存在最小生成树则返回 − 1 -1 −1。
直接用Kruskal算法。对边按照边权由小到大排序,然后遍历边,只要不会产生环,就依次将边加入。代码如下:
import java.util.Arrays;
public class Solution {
class UnionFind {
private int[] parent;
// group记录当前有多少个连通分量
private int group;
public UnionFind(int n) {
parent = new int[n];
for (int i = 0; i < parent.length; i++) {
parent[i] = i;
}
group = n;
}
private int find(int x) {
if (x != parent[x]) {
parent[x] = find(parent[x]);
}
return parent[x];
}
// 返回加入边(x, y)之后会不会产生环
private boolean union(int x, int y) {
int px = find(x), py = find(y);
if (px == py) {
return false;
}
parent[px] = py;
// 将两个连通分量合并了之后连通分量个数少一个
group--;
return true;
}
public int getGroup() {
return group;
}
}
public int minimumCost(int N, int[][] connections) {
Arrays.sort(connections, (c1, c2) -> Integer.compare(c1[2], c2[2]));
int res = 0;
UnionFind uf = new UnionFind(N);
for (int[] connection : connections) {
if (uf.union(connection[0] - 1, connection[1] - 1)) {
res += connection[2];
}
}
// 连通分量等于1说明找到了最小生成树,否则说明原图不连通,返回-1
return uf.getGroup() == 1 ? res : -1;
}
}
时间复杂度 O ( E log E ) O(E\log E) O(ElogE)(主要花在排序上了),空间 O ( V ) O(V) O(V)。