栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

最短路之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]);
	}
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/572039.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号