给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数。
请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出impossible。
数据保证不存在负权回路。
第一行包含整数n和m。
接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。
输出一个整数,表示1号点到n号点的最短距离。
如果路径不存在,则输出”impossible”。
1≤n,m≤1051≤n,m≤105,
图中涉及边长绝对值均不超过10000。
3 3
1 2 5
2 3 -3
1 3 4
2
1 #include <bits/stdc++.h> 2 using namespace std; 3 //优化的贝尔曼福特算法,就是spfa算法,用更新过的点去更新和它相连接的点 4 const int N = 1e5+10; 5 vector<int> h(N, -1), e(N, 0), w(N,0), ne(N, 0); 6 int idx; 7 vector<int> dist(N, 0x3f3f3f3f); 8 vector<bool> flag(N,false);//代表该节点当前是否在队列里 9 int n, m; 10 11 void add(int a, int b, int c){ 12 w[idx] = c; e[idx] = b; 13 ne[idx] = h[a]; 14 h[a] = idx ++; 15 } 16 17 int spfa(){ 18 queue<int> q;//队列中存储的是已经更新过用来更新其他节点的点 19 q.push(1); 20 dist[1] = 0; 21 flag[1] = true; 22 while(!q.empty()){ 23 int t = q.front(); q.pop(); 24 flag[t] = false;//不在队列里 25 for(int i = h[t];i != -1;i = ne[i]){ 26 int j = e[i]; 27 //更新成功 28 if(dist[j] > dist[t] + w[i]){ 29 dist[j] = dist[t] + w[i]; 30 if(!flag[j]) {//如果j不在队列里 31 q.push(j); 32 flag[j] = true;//放进队列里 33 } 34 } 35 } 36 } 37 return dist[n] == 0x3f3f3f3f ? -1 : dist[n]; 38 } 39 40 int main(){ 41 cin >> n >> m; 42 while(m--){ 43 int x, y, z; 44 cin >> x >> y >> z; 45 add(x, y, z); 46 } 47 int t = spfa(); 48 if(t == -1) cout << "impossible" << endl; 49 else cout << t << endl; 50 }
end
原文:https://www.cnblogs.com/sxq-study/p/12236587.html