问题描述
给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。
输入格式
第一行两个整数n, m。
接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。
输出格式
共n-1行,第i行表示1号点到i+1号点的最短路。
样例输入
3 3
1 2 -1
2 3 -1
3 1 2
样例输出
-1
-2
数据规模与约定
对于10%的数据,n = 2,m = 2。
对于30%的数据,n <= 5,m <= 10。
对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。
使用Bellman-Ford算法:
import java.util.Scanner;
public class ShortestPath {
public static void main(String[] args) {
long inf = Long.MAX_VALUE;
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[] u = new int[m+2];
int[] v = new int[m+2];
int[] w = new int[m+2];
long[] dis = new long[n+2];
long[] bak = new long[n+2];//dis数组备份
//初始化dis数组
for(int i=2; i<=n; i++) {
dis[i] = inf;
}
for(int i=1; i<=m; i++) {
u[i] = sc.nextInt();
v[i] = sc.nextInt();
w[i] = sc.nextInt();
}
sc.close();
int flag;
for(int i=1; i<=n-1; i++) {
for(int k=1; k<=n; k++) bak[k] = dis[k];//dis数组备份至bak
for(int j=1; j<=m; j++) {
if(dis[u[j]] < inf && dis[v[j]] > dis[u[j]] + w[j]) dis[v[j]] = dis[u[j]] + w[j];
}
//检测dis数组是否有更新
flag = 0;
for(int k=1; k<=n; k++) {
if(dis[k] != bak[k]) {
flag=1;
break;
}
}
if(flag == 0) break;//若没有更新,提前退出for循环
}
//输出
for(int i=2; i<=n; i++) {
System.out.println(dis[i]);
}
}
}