bellman-ford演算法求K短路O(n*m),以及判負環O(n*m)
阿新 • • 發佈:2020-09-19
#include<iostream> #include<algorithm> #include<cstring> using namespace std; const int N=510,M=1e4+10; int n,m,k,dis[N],backup[N]; //dis陣列表示dis[i]到起點的距離。 struct { int a,b,w; }edge[M]; //bellman-ford可以求出來圖中有沒有負權迴路。 //迭代k次返回的數表示:從起點經過不超過k條邊到各個點的最短距離 /* bellman-ford可以判斷負環O(n*m),如果第n次迭代仍然有更新,則說明找到 了n條邊的最短路徑,如果一條最短路徑上有n條邊, 即有n+1個點,根據抽屜原理,說明有負環。 一般用spfa演算法判斷負環 */ int bellman_ford()//直接返回k短路的距離,當k==m時返回起點到終點的最短距離 { memset(dis,0x3f,sizeof dis); dis[1]=0; for(int i=0;i<k;i++)//k次迭代,沒次迭代每次得到一個 //到起點的最近的鄰居點。 { //防止出現串聯的情況 memcpy(backup,dis,sizeof dis); for(int j=0;j<m;j++)//列舉所有的m條邊 { int a=edge[j].a,b=edge[j].b,w=edge[j].w; dis[b]=min(dis[b],backup[a]+w); } } if(dis[n]>0x3f3f3f3f/2)return -1; return dis[n]; } int main() { cin>>n>>m>>k; for(int i=0;i<m;i++) { scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].w); } int t=bellman_ford(); if(t==-1) cout<<"impossible"; else cout<<t; return 0; }