单源最短路径(贪心)

本文深入讲解了Dijkstra算法,一种用于解决带权有向图中单源最短路径问题的经典算法。通过实例演示了算法的具体实现过程,包括数据结构的选择、关键步骤的解析以及最终结果的展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

给定带权有向图 G=(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在计算从源到所有其他各顶点的最短长度。这里的长度指路上各边权之和。
在这里插入图片描述

算法设计

给定带权有向图 G=(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在计算从源到所有其他各顶点的最短长度。这里的长度指路上各边权之和。

数据结构选择

带权邻接矩阵a记录结点之间的权值, 数组dist来记录从源点到其它顶点的最短路径长度, 数组pre来记录最短路径;

结果展示

在这里插入图片描述

代码实现

package test;

public class Test2 {
	/**
	 * Dijkstra 算法
	 * @param v 源
	 * @param a 记录节点之间的权重
	 * @param dist 源点到其他顶点之间的最短路径长度
	 * @param prev 记录最短路径
	 */
	public static void dijkstra(int v,float[][] a,float[] dist,int[] prev){
		int n = dist.length-1;
		boolean[] s = new boolean[n+1];
		//初始化
		for(int i = 1;i <= n;i++){
			dist[i] = a[v][i];
			s[i] = false;
			if(dist[i] == Float.MAX_VALUE)
				prev[i] = 0;
			else
				prev[i] = v;
		}
		//源点路径为0
		dist[v] = 0;
		s[v] = true;
		
		for(int i = 1;i < n;i++){
			float temp = Float.MAX_VALUE;
			int u = v;
			for(int j = 1;j <= n;j++){
				if((!s[j])&&(dist[j]<temp)){
					u = j;
					temp = dist[j];
				}
			}
			//找出次小的节点
			s[u]=true;
			for(int j = 1;j <= n;j++)
				if((!s[j])&&(a[u][j]<Float.MAX_VALUE)){
					float newdist = dist[u]+a[u][j];
					if(newdist<dist[j]){
						dist[j]=newdist;
						prev[j]=u;
					}
				}
		}
		
		
	}
	public static void main(String[] args) {
		float[][]a = new float[6][6];
		for(int i = 1;i<6;i++ )
			for(int j = 1;j<6;j++)
				a[i][j] = Float.MAX_VALUE;
		a[1][2] = 10;
		a[1][4] = 30;
		a[1][5] = 100;
		a[2][3] = 50;
		a[3][5] = 10;
		a[4][3] = 20;
		a[4][5] = 60;
		
		a[1][1] = 0;
		a[2][2] = 0;
		a[3][3] = 0;
		a[4][4] = 0;
		a[5][5] = 0;
		float[] dist = new float[6];
		int[] prev = new int[6];
		int v = 1;
		dijkstra(v,a,dist,prev);
		
		System.out.println("该图的邻接矩阵为:");
		for(int i = 1;i<6;i++ ){
			for(int j = 1;j<6;j++){
				System.out.print(a[i][j]+"	");
			}
		System.out.println();
		}
		System.out.println("最短路径长度:");
		for(int i = 1;i<6;i++)
			System.out.print(dist[i]+"	");
		System.out.println();
		System.out.println("最短路径为:");
		for(int i = 1;i<6;i++)
			System.out.print(prev[i]+"	");
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Ma.01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值