最小生成树能够保证整个拓扑图的所有路径之和最小,但不能保证任意两点之间是最短路径。
import java.util.Arrays;
import java.util.Comparator;
public class MyKruskal {
public static final int N = 100000;// 用10000表示两个结点之间不能连接,或者也可以用Integer.MAX_VALUE
public static void main(String[] args) {
int[][] map = {
{
N, 12, N, N, N, 16, 14},
{
12, N, 10, N, N, 7, N},
{
N, 10, N, 3, 5, 6, N},
{
N, N, 3, N, 4, N, N},
{
N, N, 5, 4, N, 2, 8},
{
16, 7, 6, N, 2, N, 9},
{
14, N, N, N, 8, 9, N}
};
kruskal(map);
}
public static void kruskal(int[][] map) {
int numOfVertex = map.length;// 结点的数量
int numOfEdge = 0;// 边的数量
for (int i = 0; i < numOfVertex; i++) {
for (int j = i + 1; j < numOfVertex; j++) {
if (map[i][j] != N) {
numOfEdge++;
}
}
}
// 根据邻接矩阵得到边集数组
Edge[] edges = new Edge[numOfEdge];
int index = 0;
for (int i = 0; i < numOfVertex; i++) {
for (int j = i + 1; j < numOfVertex; j++) {
if (map[i][j] != N) {
edges[index++] = new Edge(i, j, map[i][j]);
}
}
}
// 对边集数组进行排序
Arrays.sort(edges, new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
return o1.weight - o2.weight;
}
});
UF uf = new UF(numOfVertex);
for (int i = 0; i < numOfEdge; i++) {
if (uf.union(edges[i].from, edges[i].to)) {
System.out.println("<" + "from = " + edges[i].from + ", to = " + edges[i].to + ">的权值是:" + edges[i].weight);
}
}
}
}
class Edge {
int from;// 边的起始顶点
int to;// 边的终止顶点
int weight;// 边的权值
public Edge(int from, int to, int weight) {
this.from = from;
this.to = to;
this.weight = weight;
}
@Override
public String toString() {
return "Edge{" + "from=" + from + ", to=" + to + ", weight=" + weight + '}';
}
}
class UF {
int[] parent;
int[] size;
public UF(int n) {
parent = new int[n];
size = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
size[i] = 1;
}
}
public int find(int x) {
while (x != parent[x]) {
parent[x] = parent[parent[x]];
x = parent[x];
}
return x;
}
public boolean union(int p, int q) {
int rootP = find(p);
int rootQ = find(q);
if (rootP == rootQ) {
return false;
}
if (size[rootP] > size[rootQ]) {
parent[rootQ] = rootP;
size[rootP] += size[rootQ];
} else {
parent[rootP] = rootQ;
size[rootQ] += size[rootP];
}
return true;
}
}