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标记数组,检查所有节点是否全部接入最小生成树。若存在未标记节点,判定当前图不连通,无法生成最小生成树;若所有节点成功接入,则输出累加得到的最小生成树总权重。

相关推荐
net3m3337 分钟前
一阶软件低通滤波器算法
人工智能·算法
水木流年追梦1 小时前
大模型入门-大模型优化方法12-YaRN 长文本外推技术
人工智能·分布式·算法·正则表达式·prompt
J-Tony111 小时前
【JVM】三色标记法
java·jvm·算法
wengad2 小时前
机器学习实践理论基础|算法、模型和数据集
人工智能·算法·机器学习
梦梦代码精3 小时前
为什么这个开源的AI平台会火?有点东西。。。
人工智能·算法·机器学习·docker·开源
随意起个昵称3 小时前
线性dp-综合刷题1(Not Alone)
算法·动态规划
如何原谅奋力过但无声4 小时前
【灵神高频面试题合集09-13】二叉树、二叉搜索树
数据结构·算法·leetcode
皆圥忈4 小时前
磁盘物理结构与文件系统基础讲解
linux·算法
数据仓库搬砖人4 小时前
用 LangGraph 从零搭一个客服 Agent:多轮对话 + 工具调用全流程
算法
GuWenyue4 小时前
告别JS类型坑!Ts为什么在ai时代逐渐成为"第一"语言
前端·算法·typescript