前言
这个算法的普通版本时间复杂度是O(n^2),据说是可优化的。
邻接表+最小堆。然而我并没有去实现。
不过此未经优化的版本适合稠密图,Kruskal解决稀疏图,岂不美哉= =
好吧,我就是懒了
已实现利用最小堆+邻接表优化:
http://blog.youkuaiyun.com/xubaifu1997/article/details/52068329
实现功能
实现最小生成树路径长度的计算
中文版参考
/**
* Prim算法
* 同样假设所有顶点未连接
6 9
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2
*
* 从顶点1开始,寻找顶与点1可连接所有的顶点
* 找到
* 1→2,权值为1
* 1→3,权值为2
* 选择权值最低的2号顶点,连接顶点1、2;
*
* 寻找与顶点1、2可连接的所有顶点
* 找到
* 1→2(此点排除,2已被作为末端连接)
* 1→3 权值2
* 2→3 权值6
* 2→4 权值11
* 选择1→3
* 寻找1、2、3可连接的所有顶点
* (排除以1、2、3作为末端的选项)找到
* 2→4 权值11
* 3→4 权值9
* 3→5 权值13
* 选择3→4
* 其余点的操作类似
*
* 这个过程中唯一的问题是,脑袋会受到最短路径思想的影响
* 假设
* 1→2权值1
* 1→3权值5
* 选择顶点4时,1→2→4的总长度是12
* 1→3→4的总长度为14
* 碰到这样一开始觉得好奇怪,后来画了个图,发现虽然1到4经过2,单条路径长度最短,总体生成的树却更长
* 3→1→2→4长度17
* 2→1→3→4长度15
* 所以每次选择 距离[任意一个已连接末端顶点] 最短的顶点,而不是距离首个顶点最短的顶点
*
* 解决了疑问,马上写代码
*/
代码实现
public class MinGenerationTreePrim {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int Inf = 99;
int n, m, count, min, minIndex;
int[][] vertexes;
boolean[] isConnected;//如果某顶点作为末端顶点被连接,应该为true
int[] dis;//存储已连接顶点都未连接顶点的最短距离
int sum = 0;//存储路径长度
n = in.nextInt();
m = in.nextInt();
vertexes = new int[n][n];
isConnected = new boolean[n];
dis = new int[n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i == j) {
vertexes[i][j] = 0;
} else {
vertexes[i][j] = Inf;
}
}
}
for (int i = 0, a, b, c; i < m; i++) {
a = in.nextInt();
b = in.nextInt();
c = in.nextInt();
vertexes[a - 1][b - 1] = c;
vertexes[b - 1][a - 1] = c;
}
//初始化dis数组
minIndex = 0;
count = 0;
for (int i = 0; i < n; i++) {
dis[i] = vertexes[0][i];
}
while (count < n) {
min = Inf;
//寻找权值最小的
for (int i = 0; i < n; i++) {
if (!isConnected[i] && dis[i] < min) {
min = dis[i];
minIndex = i;
}
}
sum += min;
//System.out.println(min);
isConnected[minIndex] = true;
count++;
//在minIndex之前的所有顶点已经对dis更新过了
//所以只需要更新minIndex顶点到其他顶点是否还有更短的距离
for (int i = 0; i < n; i++) {
if (!isConnected[i] && dis[i] > vertexes[minIndex][i]) {
dis[i] = vertexes[minIndex][i];
}
}
}
System.out.println(sum);
}
}
结果
输入
6 9
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2
输出
19