最短路之Bellman-ford算法java代码模板

Posted 知道什么是码怪吗?

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最短路之Bellman-ford算法java代码模板相关的知识,希望对你有一定的参考价值。

注意事项:

如果图中存在负权回路,那么不一定存在最短路。因为如果在负权回路里无限循环最后走出来最短路为负无穷。

例如下图:

但是我们上面说的是如果存在负权回路,不一定存在最短路。为什么呢?因为只要这个负权回路不在初始点到末尾点的路径上,那这个负权回路对最短路没有影响。

思想:

① 两层循环,第一层循环循环n次,n代表节点的个数。

②第二层循环循环m次,m代表边的条数。每次内层循环比较当前边终点存放的距离当前边起点存放的距离+这条边长度的关系,如果终点存放的距离大于起点存放的距离+这条边的长度,那么更新终点存放的距离。

如下图所示,就会发生更新。 

代码:

import java.util.Arrays;
import java.util.Scanner;

public class Main 
	static int[][] way = new int[10010][3];// 存放边
	static int[] dist = new int[510];// 存放到某点的距离
	static int[] temp = new int[3];// 存放单条边
	static int n, m, k;

	public static void Bellman_Ford() 
		Arrays.fill(dist, Integer.MAX_VALUE / 10);// 初始化
		dist[1] = 0;
		for (int i = 0; i < n; i++) // n代表节点的个数
			for (int j = 0; j < m; j++) // m代表边的条数
				temp = way[j];//获取边
				dist[temp[1]] = Math.min(dist[temp[1]], dist[temp[0]] + temp[2]);//更新
			
		
	
	
	public static void main(String args[]) 
		Scanner input = new Scanner(System.in);
		n = input.nextInt();
		m = input.nextInt();
		k = input.nextInt();
		for (int i = 0; i < m; i++) 
			way[i][0] = input.nextInt();
			way[i][1] = input.nextInt();
			way[i][2] = input.nextInt();
		
		Bellman_Ford();
		if (dist[n] > Integer.MAX_VALUE / 20)
			System.out.println("不存在最短路径");
		else
			System.out.println(dist[n]);
	

例题:

给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环, 边权可能为负数

请你求出从 1 号点到 n 号点的最多经过 k 条边的最短距离,如果无法从 1 号点走到 n 号点,输出 impossible

注意:图中可能 存在负权回路 。

输入格式

第一行包含三个整数 n,m,k。

接下来 m 行,每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。

输出格式

输出一个整数,表示从 1 号点到 n 号点的最多经过 k 条边的最短距离。

如果不存在满足条件的路径,则输出 impossible

数据范围

1≤n,k≤500,
1≤m≤10000,
任意边长的绝对值不超过 10000。

输入样例:

3 3 1
1 2 1
2 3 1
1 3 3

输出样例:

3

解题代码:

import java.util.Arrays;
import java.util.Scanner;


public class Main 
	static int[][] way = new int[10010][3];// 存放边
	static int[] dist = new int[510];// 存放到某点的距离
	static int[] last = new int[510];// ***存放上一次循环各点的距离***
	static int[] temp = new int[3];// 存放单条边
	static int n, m, k;

	public static void Bellman_Ford() 
		Arrays.fill(dist, 50000);// 初始化
		dist[1] = 0;
		for (int i = 0; i < k; i++) 
			last = Arrays.copyOfRange(dist, 0, dist.length);// 将上一次的结果复制给last
			for (int j = 0; j < m; j++) 
				temp = way[j];
				dist[temp[1]] = Math.min(dist[temp[1]], last[temp[0]] + temp[2]);
			
		
	

	public static void main(String args[]) 
		Scanner input = new Scanner(System.in);
		n = input.nextInt();
		m = input.nextInt();
		k = input.nextInt();
		for (int i = 0; i < m; i++) 
			way[i][0] = input.nextInt();
			way[i][1] = input.nextInt();
			way[i][2] = input.nextInt();
		
		Bellman_Ford();
		if (dist[n] > 25000)// 存在负权边,不能直接等于
			System.out.println("impossible");
		else
			System.out.println(dist[n]);
	

以上是关于最短路之Bellman-ford算法java代码模板的主要内容,如果未能解决你的问题,请参考以下文章

算法入门之完美单源最短路径:Bellman-Ford(贝尔曼-福特)算法

最短路径之Bellman-Ford算法

Python 图_系列之纵横对比 Bellman-Ford 和 Dijkstra 最短路径算法

C++ 图进阶系列之纵横对比 Bellman-Ford 和 Dijkstra 最短路径求解算法

Bellman-ford 单源最短路径算法

数据结构-图的遍历之Bellman-Ford算法和SPFA算法