原题链接
①. 题目
②. 思路
不能使用 Dijkstra 解决含负权图的问题
- 其原理为连续进行松弛,在每次松弛时把每条边都更新一下,若在 n-1 次松弛后还能更新,则说明图中有负环,因此无法得出结果,否则就完成。
- bellman - ford算法擅长解决有边数限制的最短路问题。
BellMan-Ford算法步骤
for n次
for 所有边 a,b,w (松弛操作)
dist[b] = min(dist[b],back[a] + w)
back[] 数组是上一次迭代后 dist[] 数组的备份
- back[] 数组是上一次迭代后 dist[] 数组的备份,由于是每个点同时向外出发,因此需要对 dist[] 数组进行备份,若不进行备份会因此发生串联效应,影响到下一个点
③. 学习点
Bellman-Ford算法
④. 代码实现
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
static int N=510;
static int M=100010;
static int n,m,k;
static int[] dist=new int[N];
static Node[] list=new Node[M];
static int INF=0x3f3f3f3f;
static int[] back=new int[N];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] s = br.readLine().split(" ");
n=Integer.parseInt(s[0]);
m=Integer.parseInt(s[1]);
k=Integer.parseInt(s[2]);
for (int i = 0; i <m; i++) {
String[] s2 = br.readLine().split(" ");
int a = Integer.parseInt(s2[0]);
int b = Integer.parseInt(s2[1]);
int c = Integer.parseInt(s2[2]);
list[i]=new Node(a,b,c);
}
bellman_ford();
}
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++) {
Node node=list[j];
int a=node.a;
int b=node.b;
int c=node.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]);
}
}
class Node{
int a,b,c;
public Node(int a,int b,int c) {
this.a=a;
this.b=b;
this.c=c;
}
}