WUSTOJ 1305: 最短路(Java)
题目链接:🔗1305: 最短路
参考百度百科:🔗Bellman-Ford算法(我觉得这个写的好点)或🔗贝尔曼-福特算法
Description
给定一个个顶点,条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从号点到其他点的最短路(顶点从到编号)。
Input
第一行两个整数, 。
接下来的行,每行有三个整数, , ,表示到有一条长度为的边。
Output
共行,第行表示号点到号点的最短路。
Sample Input
3 3
1 2 -1
2 3 -1
3 1 2
Sample Output
-1
-2
HINT
数据规模与约定
对于10%的数据,,。
对于30%的数据,,。
对于100%的数据,,,,保证从任意顶点都能到达其他所有顶点。
分析💬
感觉这道题就是专门为Bellman-Ford算法而设计的。
- 初始1号点与其他所有点距离为正无穷(47483647),
1号点与自己距离为0,
1号点与以1号点为弧尾的弧的弧头的距离为弧的长度。 - 松弛操作,有n个点,最多循环n-1次,每次遍历所有的边,
如果1号点与弧头的距离大于1号点与弧尾的距离加弧的长度,即
dis[arc[j].head] > dis[arc[j].tail] + arc[j].cost
那么就需要更新1号点与弧头的距离为较小的值,
否则遍历下一条边。 - 直到第i次循环,所有的边都没有进行松弛操作,退出循环。
- 输出1号点与其他点的距离即为最短路。
代码💻
/**
* Time 2526ms
* @author wowpH
* @version 1.1
* @date 2019年6月10日上午10:52:40
* Environment: Windows 10
* IDE Version: Eclipse 2019-3
* JDK Version: JDK1.8.0_112
*/
import java.io.InputStreamReader;
import java.util.Scanner;
public class Main {
private final Scanner sc = new Scanner(new InputStreamReader(System.in));
private int n, m; // 顶点数,边数
private int[] dis; // 1号点与i点的距离为dis[i],下标从1开始
private Arc[] arc; // 弧,下标从0开始
public Main() {
while (sc.hasNext()) {
init();// 输入并初始化
relaxation();// 松弛操作
for (int i = 2; i <= n; ++i) {// 输出1号点距离其他点的最短路径
System.out.println(dis[i]);
}
}
sc.close();
}
private void init() {// 输入并初始化
n = sc.nextInt();
m = sc.nextInt();
dis = new int[n + 1];
dis[1] = 0;// 1号点与自己距离为0
for (int i = 2; i <= n; ++i) {
dis[i] = 47483647;// 1号点与i点距离初始化为47483647(正无穷),i>1
}
arc = new Arc[m];// m条弧
for (int i = 0; i < m; ++i) {
arc[i] = new Arc();
arc[i].tail = sc.nextInt();
arc[i].head = sc.nextInt();
arc[i].cost = sc.nextInt();
// 如果弧尾是1号点,那么1号点与弧头的距离为弧权值
if (1 == arc[i].tail) {
dis[arc[i].head] = arc[i].cost;
}
}
}
private void relaxation() {// 松弛操作
boolean flag;// 是否松弛操作
for (int i = 1; i < n; ++i) {// 最多n-1次松弛操作
flag = false;// 未进行松弛操作
for (int j = 0; j < m; ++j) {// 所有边进行松弛操作判断
if (dis[arc[j].head] > dis[arc[j].tail] + arc[j].cost) {
dis[arc[j].head] = dis[arc[j].tail] + arc[j].cost;
flag = true;// 进行了松弛操作
}
}
if (false == flag) {// 未进行松弛操作,结束
break;
}
}
}
public static void main(String[] args) {
new Main();
}
}
class Arc {
int tail;// 弧尾
int head;// 弧头
int cost;// 花费,长度,权值
}
版权声明:
- 转载请于首页注明链接形式的WUSTOJ 1305: 最短路(Java)——wowpH;
- 代码原创,公开引用不能删除首行注释(作者,版本号,时间等信息);
- 如果有疑问欢迎评论区留言,尽量解答;
- 如果有错误,还望大侠评论区指正。