一 思路
prim算法核心就是三步,我称为prim三部曲,大家一定要熟悉这三步,代码相对会好些很多:
- 第一步,选距离生成树最近节点
- 第二步,最近节点加入生成树
- 第三步,更新非生成树节点到生成树的距离(即更新minDist数组)
二 minDist 数组是什么
minDist数组 用来记录 每一个节点距离最小生成树的最近距离
三 模板
java
import java.util.*;
public class Main {
public static void main(String[] args) {
// 创建一个Scanner对象来读取用户输入
Scanner input = new Scanner(System.in);
// 读取顶点数和边数
int v = input.nextInt(); // 顶点的数量
int e = input.nextInt(); // 边的数量
// 初始化邻接矩阵,所有距离初始化为10001(这里假设10001是一个足够大的数,表示无穷大)
int[][] map = new int[v + 1][v + 1];
for (int i = 0; i <= v; i++) {
Arrays.fill(map[i], 10001);
}
// 读取边的信息,并更新邻接矩阵
for (int i = 0; i < e; i++) {
int v1 = input.nextInt(); // 边的起点
int v2 = input.nextInt(); // 边的终点
int val = input.nextInt(); // 边的权重
map[v1][v2] = val; // 更新邻接矩阵,表示v1到v2的距离为val
map[v2][v1] = val; // 因为是无向图,所以v2到v1的距离也是val
}
// 初始化一个布尔数组,用于标记顶点是否已经被加入到最小生成树中
boolean[] isInTree = new boolean[v + 1];
Arrays.fill(isInTree, false);
// 初始化一个数组,用于存储每个顶点到最小生成树的最小距离
int[] minDis = new int[v + 1];
Arrays.fill(minDis, 10001);
// Prim算法的主循环
for (int i = 1; i < v; i++) {
int minVal = Integer.MAX_VALUE; // 初始化最小值为无穷大
int point = -1; // 用于存储当前最小距离的顶点
// 寻找当前未加入最小生成树的顶点中,距离最小的顶点
for (int j = 1; j <= v; j++) {
if (!isInTree[j] && minDis[j] < minVal) {
minVal = minDis[j];
point = j;
}
}
// 将找到的顶点加入到最小生成树中
isInTree[point] = true;
// 更新与point相连的顶点的最小距离
for (int k = 0; k <= v; k++) {
if (!isInTree[k] && minDis[k] > map[point][k]) {
minDis[k] = map[point][k];
}
}
}
// 计算最小生成树的总权重
int ret = 0;
for (int i = 2; i <= v; i++) {
ret += minDis[i];
}
// 输出最小生成树的总权重
System.out.println(ret);
}
}