给定一个 nn 个点 mm 条边的有向图,图中可能存在重边和自环, 边权可能为负数
请你求出 11 号点到 nn 号点的最短距离,如果无法从 11 号点走到 nn 号点,则输出 impossible。
数据保证不存在负权回路。

输入格式

第一行包含整数 nn 和 mm。
接下来 mm 行每行包含三个整数 x,y,zx,y,z,表示存在一条从点 xx 到点 yy 的有向边,边长为 zz。

输出格式

输出一个整数,表示 11 号点到 nn 号点的最短距离。
如果路径不存在,则输出 impossible。

数据范围

1≤n,m≤1051≤n,m≤105,
图中涉及边长绝对值均不超过 1000010000。

输入样例:

3 3 1 2 5 2 3 -3 1 3 4

输出样例:

2


  1. #include <iostream>
  2. #include <cstring>
  3. #include <queue>
  4. using namespace std;
  5. const int N = 100010;
  6. int h[N],e[N],ne[N],w[N],idx;
  7. int dist[N];
  8. bool st[N];
  9. int n,m;
  10. void add(int a, int b, int c){
  11. e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
  12. }
  13. int spfa(){
  14. memset(dist,0x3f,sizeof dist);
  15. dist[1] = 0;
  16. queue<int> q;
  17. q.push(1);
  18. st[1] = true;
  19. while(q.size()){
  20. int t = q.front();
  21. q.pop();
  22. st[t] = false;
  23. for(int i = h[t]; i != -1; i = ne[i]){
  24. int j = e[i];
  25. if(dist[j] > dist[t] + w[i]){
  26. dist[j] = dist[t] + w[i];
  27. if(!st[j]){
  28. q.push(j);
  29. st[j] = true;
  30. }
  31. }
  32. }
  33. }
  34. if(dist[n] > 0x3f3f3f3f / 2) return -2;
  35. return dist[n];
  36. }
  37. int main(){
  38. cin >> n >> m;
  39. memset(h,-1,sizeof h);
  40. while(m--){
  41. int a,b,c;
  42. cin >> a >> b >> c;
  43. add(a,b,c);
  44. }
  45. int a = spfa();
  46. if(a == -2) cout << "impossible" << endl;
  47. else cout << a << endl;
  48. return 0;
  49. }