prim算法最小生成树(java)

prim算法是解决最小生成树的经典算法,在算法竞赛中很常见。以下给出使用java实现prim算法的代码和具体过程。

java 复制代码
import java.sql.Array;
import java.util.Arrays;
import java.util.Scanner;

public class Prim算法 {
	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt(),m = scan.nextInt();
		//n,m分别表示节点数和边数
		//默认是1-n个节点
		int[][] arr = new int[n+1][n+1];
		
		//输入节点相连的边和边上的权值
		int a = 0,b = 0,v = 0;
		for(int i = 0;i<m;i++) {
			a = scan.nextInt();
			b = scan.nextInt();
			v = scan.nextInt();
			arr[a][b] = v;
			arr[b][a] = v;
			
		}
		
		//因为prim算法每次只找一个边,而一个边连接一个已访问节点和一个未访问节点
		//所以每次记录一个节点就表示记录一条边
		//找到所有已经标记的边中最小权值的边(节点)
		//并将该节点的所有相邻节点记录

		int[] log = new int[n+1];
		Arrays.fill(log, 2000);
		boolean[] flags = new boolean[n+1];
		Arrays.fill(flags,false);
		//初始化
		
		int cur_point= 1;
		log[cur_point] = 0;
		//true表示已经标记了
		flags[cur_point] = true;
		int count = 0;
		
		for(int i = 1;i<=n-1;i++) {
			//将当前节点的相邻节点记录
			for(int j = 1;j<=n;j++) {
				if(arr[cur_point][j]!=0&&arr[cur_point][j]<log[j]) {
					log[j] = arr[cur_point][j];
				}
			}
			//找到log数组中的最小值
			int temp = 0;
			int min_num = 2000;
			for(int j = 1;j<=n;j++) {
				if(!flags[j]&&log[j]<min_num) {
					min_num = log[j];
					temp = j;
				}
			}
			//处理单个节点
			if(temp!=0) {
				flags[temp] = true;
				cur_point = temp;
			}else {
				break;
			}
			count+=min_num;
		}
		//还需判断当前图是否联通
		for(int i = 1;i<=n;i++) {
			if(!flags[i]) {
				System.out.println("当前图不连通");
				return;
			}
		}
		System.out.println(count);
		scan.close();
	}
}

1.输入输出

输入:无向图的节点数、边数,以及每条边的两个端点和权值;

核心逻辑:从 1 号节点出发,逐步选择 "连接已访问节点集和未访问节点集" 的最小权值边,最终累加所有边的权值得到最小生成树总权值;

输出:若图连通,输出最小生成树总权值;若不连通,输出 "当前图不连通"。

2.相关变量

log数组:核心状态数组,logj 记录 "从已访问节点集到未访问节点j" 的最小权值边(初始值 2000 表示 "无穷大",代表暂时无连接);

flags数组:标记节点是否已加入最小生成树(true= 已加入);

cur_point:当前已加入生成树的 "最新节点"(初始为 1 号);

count:最终要输出的最小生成树总权值。

3.实现思路

最小生成树包含 n 个节点、n-1 条边,因此程序循环 n-1 次完成边的选取,核心分为两个步骤:

  1. 更新邻接节点权重:遍历当前已接入生成树节点的所有相邻节点,若节点间存在连通边,且该边权重小于log数组中记录的节点最短权重,则更新log数组,实时刷新未接入节点到生成树的最小距离。

  2. 选取最优接入节点:遍历所有未接入生成树的节点,筛选出log数组中权重最小的节点,该节点即为当前可接入生成树、开销最小的节点。将该节点标记为已接入,更新当前遍历节点,并累加边的权重,统计最小生成树总权重。若遍历无可用节点,说明图无法继续连通,直接终止迭代。

迭代结束后,遍历flags标记数组,检查所有节点是否全部接入最小生成树。若存在未标记节点,判定当前图不连通,无法生成最小生成树;若所有节点成功接入,则输出累加得到的最小生成树总权重。

相关推荐
不会代码的小猴14 分钟前
3. 控件学习1
开发语言·c++·笔记·qt·算法
203号居民2 小时前
LeetCode hot 100 —41. 缺失的第一个正数
数据结构·算法·leetcode
专注仿真4 小时前
问答大模型技术方案算法实现-熵权法融合算法 + 交叉编码器重排算法
人工智能·python·算法·语言模型·问答大模型关键算法·熵权融合算法·交叉编码器重排算法
地平线开发者5 小时前
量化为什么会有损失:从量化误差到精度下降
算法
手写码匠6 小时前
华为云Flexus+DeepSeek征文|Dify 多 Agent 会话管理与上下文工程实战:让智能体“记住该记住的,忘掉该忘掉的“
人工智能·深度学习·算法·aigc
2401_862880826 小时前
数据结构 --- 栈
c语言·数据结构·算法
致Great6 小时前
Qwen3.8-27B 接入 DSH 全流程实测:写代码、跑长任务,都没问题
算法
Tisfy7 小时前
LeetCode 3471.找出最大的几近缺失整数:三种情况判断
算法·leetcode·题解·分类讨论
linux-hzh7 小时前
百日算法修炼 · Day 12
算法·深度优先
额额额对了7 小时前
数据结构:二叉树
c语言·数据结构·算法