图论---Bellman-Ford算法
适用场景:有边数限制 ->(有负环也就没影响了),存在负权边,O( n * m );
有负权回路时有的点距离会是负无穷,因此最短路存在的话就说明没有负权回路。
从1号点经过不超过k条边到每个点的距离。
若经过n次迭代,有更新的话(经过n+1个点了)就说明存在负环(一般不用其来求,用SPFA来判断负环)。
只有负环在1号点到n号点的路径上时,最短路才会不存在,在别的路上不影响。
有负环不会死循环,但是值可能会很小
#include<bits/stdc++.h>
using namespace std;
const int N=510,M=10010;
int n,m,k;
int dist[N],backup[N];
struct edge{int a,b,w;
}edges[N];
int bellman_ford(){memset(dist,0x3f,sizeof dist);dist[1]=0;for(int i=0;i<k;++i){memcpy(backup,dist,sizeof dist);//每次更新时只用上一次更新的结果for(int j=0;j<m;++j){int a=edges[j].a,b=edges[j].b,w=edges[j].w;dist[b]=min(dist[b],backup[a]+w);}}if(dist[n]>0x3f3f3f3f / 2 ) return -1; //除2的原因是可能存在负权边return dist[n];
}
int main(){scanf("%d%d%d",&n,&m,&k);for(int i=0;i<m;++i){int a,b,w;scanf("%d%d%d",&a,&b,&w);edges[i]={a,b,w};}int t=bellman_ford();if(t==-1) puts("impossible");else printf("%d\n",t);return 0;
}