Bellman-Ford算法 (貝爾曼-福特算法)


定義

貝爾曼-福特算法,求解單源最短路徑問題的一種算法,由理查德·貝爾曼(Richard Bellman) 和 萊斯特·福特 創立的。

它的原理是對圖進行松弛操作,得到所有可能的最短路徑。其優於迪科斯徹算法的方面是邊的權值可以為負數、實現簡單,缺點是時間復雜度過高。

原理

Bellman-Ford算法通過松弛(如果 dist[v] < dist[u] + w,則dist[v] = dist[u] + w),反復利用已有的邊來更新最短距離。

如果不存在負權回路,應當會在 (n-1) 次松弛之后結束。因為任意兩點間的最短路徑至多經過 (n-2) 個點,因此經過 (n-1) 次操作后就可以得到最短路徑。

如果存在負權回路,那么第 n 次松弛操作仍然會成功,Bellman-Ford算法就是利用這個性質判定負環。

實現

#include<bits/stdc++.h>
using namespace std; const int inf=0x3f3f3f3f; const int maxn=10005; struct node { int u,v,w; }edge[maxn]; int dis[maxn],n,m; int Bellman_Ford(int s); int main() { int i; scanf("%d%d",&n,&m); for(i=1;i<=m;i++)  scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w); if(Bellman_Ford(1)) printf("有負環\n"); system("pause"); return 0; } int Bellman_Ford(int s) { int check,flag=0,i,j; fill(dis,dis+maxn,inf);  dis[s]=0; for(j=1;j<=n-1;j++) { check=0; for(i=1;i<=m;i++) if(dis[edge[i].v]>dis[edge[i].u]+edge[i].w) { dis[edge[i].v]=dis[edge[i].u]+edge[i].w; check=1; } if(!check)break; } for(i=1;i<=m;i++) if(dis[edge[i].v]>dis[edge[i].u]+edge[i].w) { flag=1; break; } if(flag) return 1; else
    for(i=1;i<=n;i++) printf("%d->%d %d\n",s,i,dis[i]); return 0; }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM