给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环, 边权可能为负数。
请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 impossible。
数据保证不存在负权回路。
输入格式
第一行包含整数 n 和 m。
接下来 mm 行每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。
输出格式
输出一个整数,表示 1 号点到 n 号点的最短距离。
如果路径不存在,则输出 impossible。
数据范围
1≤n,m≤105,
图中涉及边长绝对值均不超过 10000。
输入样例:
3 3 1 2 5 2 3 -3 1 3 4
输出样例:
2
spfa是bellman算法的优化,因为不是所有边都会更新
所以用到了队列来存。
非常像dijistra算法
#include#include #include #include using namespace std; const int N=1e5+10; int dist[N]; int e[N],ne[N],h[N],w[N]; bool st[N];//表示是否在队列中,这样可以有效避免重复更新。 int idx; int n,m; void add(int a,int b,int c) { e[idx]=b;w[idx]=c;ne[idx]=h[a];h[a]=idx++; } int spfa() { memset(dist,0x3f,sizeof dist); dist[1]=0; queue q; q.push(1); st[1]=true; while(q.size()) { int t=q.front(); q.pop(); st[t]=false;//表示出列 for(int i=h[t];i!=-1;i=ne[i]) { int b=e[i],c=w[i]; if(dist[b]>dist[t]+c)//松弛的点 { dist[b]=dist[t]+c; if(!st[b])//表示不在队列中 q.push(b),st[b]=true;//已入列 } } } if(dist[n]==0x3f3f3f3f) return -2; else return dist[n]; } int main(void) { memset(h,-1,sizeof h); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } int t=spfa(); if(t==-2) puts("impossible"); else cout<



