首先放代码
public static void bellman_ford(){
Arrays.fill(dist, INF);
dist[1] = 0;
for (int i = 0; i < k; i++) {
back = Arrays.copyOf(dist,n+1);
for (int j = 0; j < m; j++) {
Edge edge = list[j];
int a = edge.a;
int b = edge.b;
int c = edge.c;
dist[b] = Math.min(dist[b], back[a]+c);
}
}
if(dist[n] > INF/2) System.out.println("impossible");
else System.out.println(dist[n]);
}
对于这一条语句:
dist[b] = Math.min(dist[b], back[a]+c);
在解决有边数限制的最短路问题时,若把back[a]变成dist[a],则可能得出错误结果,这是因为对于源点来说,
bellman
-
ford外循环的意义
为一轮循环将最多一条路径添加到源点到各点的最短路径内,这也是
bellman
-ford算法方便处理有边数限制的最短路问题的原因。
如果back[a]变成dist[a],则有可能在本轮(内)循环里a点在b点前就找到了一条新的最短路径(可能使这条路径的边数增加),而轮到b时又添加一次,一轮可能往最短路径添加多条边,则不满足题目要求的k条边。
比如有4个点ABCD,往Edge[]里存边:
A B 1
B C 1
C D 2
在扫描边BC时,把更新后的dist[A]纳入计算,在扫描边CD时,把更新后的dist[C]纳入计算,一轮循环增加了3条边,若题目要求1条边就错了。