c++ Bellman-Ford算法的具體實(shí)現(xiàn)
Bellman-Ford算法用于解決有邊數(shù)限制的最短路問(wèn)題,且可以應(yīng)對(duì)有負(fù)邊權(quán)的圖
其時(shí)間復(fù)雜度為O(nm),效率較低

代碼實(shí)現(xiàn):
#include<iostream>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int N=1e4+10;
const int M=510;
int m,n,k,dis[M],backup[M];
//m條邊,n個(gè)點(diǎn),在1號(hào)點(diǎn)到n號(hào)點(diǎn)之間找到一條經(jīng)過(guò)小于等于k條邊的通路
//dis:各點(diǎn)到源點(diǎn)的距離,backup:備份
struct Node
{
int x,y,v;
}edge[N];//可以直接用結(jié)構(gòu)體存邊
int Bellman_Ford()
{
dis[1]=0;
memset(dis,0x3f,sizeof dis);
for(int i=1;i<=k;i++)
{
memcpy(backup,dis,sizeof dis);
for(int j=1;j<=m;j++)
{
Node t=edge[j];
dis[t.y]=min(dis[t.y],backup[t.x]+t.v);
}
}
if(dis[n]>inf/2) return -1;
return dis[n];
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=m;i++)
{
int a,b,c;
cin>>a>>b>>c;
edge[i]={a,b,c};
}
int ans=Bellman_Ford();
if(ans==-1) cout<<"impossible";
else cout<<ans;
return 0;
}
對(duì)代碼中的重難點(diǎn)的解釋:
1.backup備份數(shù)組存在的意義:每一次“迭代”后,實(shí)現(xiàn)對(duì)dis數(shù)組的當(dāng)前狀態(tài)進(jìn)行保存
這里詳細(xì)解釋一下“迭代”的含義:此處的迭代即為從源點(diǎn)開(kāi)始,對(duì)所到達(dá)的點(diǎn)的出邊進(jìn)行松弛
舉個(gè)例子:有一個(gè)如下的圖,1號(hào)點(diǎn)為源點(diǎn)

第一次迭代
找到2,3號(hào)點(diǎn)到源點(diǎn)的最短距離

第二次迭代
找到4,5號(hào)點(diǎn)到源點(diǎn)的最短距離

第三次迭代
由于所有邊都已被遍歷,沒(méi)有邊能夠被松弛,迭代結(jié)束
由剛才的過(guò)程可知,每一次迭代后要對(duì)dis數(shù)組進(jìn)行備份,若一直使用dis數(shù)組進(jìn)行運(yùn)算,程序則會(huì)失去迭代的控制(在代碼中迭代體現(xiàn)為Bellman-Ford函數(shù)中的外重循環(huán),題目要求最多經(jīng)過(guò)k條邊,實(shí)際上就是最多有k次迭代)
2.代碼的最后的判斷
為什么是if(dis[n]>inf/2),而不是if(dis[n]==inf)呢?
原因是Bellman-Ford算法可能處理含負(fù)權(quán)邊的圖,dis[n]可能會(huì)出現(xiàn)+∞-2這樣的數(shù)值,所以進(jìn)行大小比較判斷時(shí)條件只需要讓dis[n]大于一個(gè)同數(shù)量級(jí)的數(shù)(此處為inf/2)即可
到此這篇關(guān)于c++ Bellman-Ford算法的具體實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)c++ Bellman-Ford內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(769.可排序的最大塊數(shù))
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(769.可排序的最大塊數(shù)),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易版掃雷的完整過(guò)程
這篇文章主要給大家介紹了關(guān)于利用C語(yǔ)言如何實(shí)現(xiàn)簡(jiǎn)易版掃雷的完整過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
利用C語(yǔ)言實(shí)踐OOP,以及new,delete的深入分析
本篇文章是對(duì)用C語(yǔ)言實(shí)踐OOP,new,delete進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
遞歸法求最大公約數(shù)和最小公倍數(shù)的實(shí)現(xiàn)代碼
今天整理了一下用遞歸法求最大公約數(shù)(gcd)和最小公倍數(shù)(lcm)。主要的工作是求最大公約數(shù)。數(shù)學(xué)上可以用輾轉(zhuǎn)法求最大公約數(shù)2013-05-05
C語(yǔ)言編程數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)詳解小白篇
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ),非常適合初學(xué)數(shù)據(jù)結(jié)構(gòu)的小白,有需要的朋友可以借鑒參考下,希望可以有所幫助,祝大家多多進(jìn)步,早日升職加薪2021-09-09
Linux系統(tǒng)中C語(yǔ)言編程創(chuàng)建函數(shù)fork()執(zhí)行解析
最近在看進(jìn)程間的通信,看到了fork()函數(shù),雖然以前用過(guò),這次經(jīng)過(guò)思考加深了理解。現(xiàn)總結(jié)如下2013-04-04
C++學(xué)習(xí)之Lambda表達(dá)式的用法詳解
Lambda?表達(dá)式(lambda?expression)是一個(gè)匿名函數(shù),Lambda表達(dá)式基于數(shù)學(xué)中的λ演算得名。本文就來(lái)為大家詳細(xì)講講C++中Lambda表達(dá)式的使用,需要的可以參考一下2022-07-07

