AcWing 858. Prim算法求最小生成树(Java)_普里姆算法_最小生成树_稠密图

原题链接

①. 题目

在这里插入图片描述

②. 思路

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 这里是稠密图,使用邻接矩阵进行存储

Prim算法步骤


	// Prim是更新不在集合中的点 离集合S的距离
	 //dist[i]距离设置为无穷大
		dist[1]=0
	  for i in 0..n-1
		    //找到不在s集合中,距离s集合最近的点t
		    //将这个点t放入集合中
		    //利用这个点t, 更新不在集合中的点
		dist[j] = min(dist[j], g[t][j])
	 

③. 学习点

普里姆算法_最小生成树

④. 代码实现

import java.util.Scanner;

public class Main {
    
    
	/*
	 * Prim是更新不在集合中的点 离集合S的距离
	 * dist[i]距离设置为无穷大
		dist[1]=0
	 * for i in 0..n-1
		    找到不在s集合中,距离s集合最近的点t
		    将这个点t放入集合中
		    利用这个点t, 更新不在集合中的点
		dist[j] = min(dist[j], g[t][j])
	 */
	static int N=510,INF=0x3f3f3f3f;
	static int g[][]=new int[N][N];//邻接矩阵
	static int dist[]=new int[N];//表示到集合的最短距离
	static boolean st[]=new boolean[N]; //记忆化数组
	static int n,m;
	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		//初始化邻接矩阵和集合距离
		for (int i = 0; i <N; i++) {
    
    
			dist[i]=INF;
			for (int j = 0; j <N; j++) {
    
    
			    //初始化邻接矩阵存储的最短距离
				g[i][j]=INF;
			}
		}
		n=sc.nextInt();m=sc.nextInt();
		while(m-->0) {
    
    
			int a=sc.nextInt(),b=sc.nextInt(),c=sc.nextInt();
			//重边取最小值
			g[a][b]=g[b][a]=Math.min(g[b][a], c);
		}
		int t=prim();
		//有点不连通的时候,不存在最小生成树
		System.out.println(t==INF?"impossible" :t);
	}
	
	static int prim() {
    
    
		int ans=0;
		for (int i = 0; i <n; i++) {
    
     //遍历n个点
			int t=-1; 
			for(int j=1;j<=n;j++) {
    
    
				//找到一个最短边权的点
				if(!st[j]&&(t==-1||dist[t]>dist[j])) {
    
    
					t=j;
				}
			}
			//不是第一个取出的节点,并且当前节点的距离为INF,则表示没有和集合中点相连的边。
			if(i!=0&&dist[t]==INF) {
    
    
			    //没有和集合中点相连的边。直接impossible
				return INF;
			}
			 //写在前面,如果一个节点本身出现负环,下面这句更新后,会影响结果,
			if(i!=0) {
    
    
			    //记录最小生成树的权值和
				ans+=dist[t];
			}
			st[t]=true;
			//更新当前最短边权点t到集合的距离(保留最小的值,如果比之前最短t到集合的距离还小,更新)
			for (int j =1; j <=n; j++) {
    
    
				dist[j]=Math.min(dist[j], g[t][j]);
			}
		}
		return ans;
	}
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45480785/article/details/114155961