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

相关推荐
lisw056 小时前
Dayhoff的PAM替换矩阵理论评介!
线性代数·算法·矩阵
一起学安全技术6 小时前
拆大模型 03|注意力的一句话版本:不用论文讲清 Attention
深度学习·算法·语言模型·transformer
Delightrs7 小时前
Rust LeetCode238 算法题解
开发语言·算法·rust
自信150413057598 小时前
重生之从0开始学习c++之——vector-中篇
c++·学习·算法
GoAI19 小时前
DeepSeek Harness Memory (一)主流记忆插件总结
后端·算法·面试
Pniubi20 小时前
力扣54.螺旋矩阵
算法·leetcode·矩阵
choumou_M1 天前
算法_1:由浅入深学习快速排序QuickSort
学习·算法·排序算法
Coder_Shenshen1 天前
罗克韦尔ACD工程归档离线变量树解析
算法·c#
心仪久了会沦陷1 天前
C语言数据结构入门——树与二叉树详解:概念、堆实现与链式遍历
c语言·数据结构·算法