生活随笔
收集整理的這篇文章主要介紹了
图的四种最短路径算法
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
本文總結(jié)了圖的幾種最短路徑算法的實(shí)現(xiàn):深度或廣度優(yōu)先搜索算法,弗洛伊德算法,迪杰斯特拉算法,Bellman-Ford算法
?
1),深度或廣度優(yōu)先搜索算法(解決單源最短路徑)
從起始結(jié)點(diǎn)開始訪問所有的深度遍歷路徑或廣度優(yōu)先路徑,則到達(dá)終點(diǎn)結(jié)點(diǎn)的路徑有多條,取其中路徑權(quán)值最短的一條則為最短路徑。
下面是核心代碼:
?
[cpp]?view plain?copy
void?dfs(int?cur,?int?dst){????????/***operation***/????????????/***operation***/????????if(minPath?<?dst)?return;//當(dāng)前走過路徑大于之前最短路徑,沒必要再走下去????????if(cur?==?n){//臨界條件????????????if(minPath?>?dst)?minPath?=?dst;????????????return;????????}????????else{????????????int?i;????????????for(i?=?1;?i?<=?n;?i++){????????????????if(edge[cur][i]?!=?inf?&&?edge[cur][i]?!=?0?&&?mark[i]?==?0){????????????????????mark[i]?=?1;????????????????????dfs(i,?dst+edge[cur][i]);????????????????????mark[i]?=?0;??//需要在深度遍歷返回時(shí)將訪問標(biāo)志置0??????????????????????????}????????????}????????????return;????????}????}????
例1:下面是城市的地圖,注意是單向圖,求城市1到城市5的最短距離。(引用的是上次總結(jié)的圖論(一)中1)的例2)
?
[cpp]?view plain?copy
/***先輸入n個(gè)結(jié)點(diǎn),m條邊,之后輸入有向圖的m條邊,邊的前兩元素表示起始結(jié)點(diǎn),第三個(gè)值表權(quán)值,輸出1號(hào)城市到n號(hào)城市的最短距離***/????/***算法的思路是訪問所有的深度遍歷路徑,需要在深度遍歷返回時(shí)將訪問標(biāo)志置0***/????#include?<iostream>????#include?<iomanip>????#define?nmax?110????#define?inf?999999999????using?namespace?std;????int?n,?m,?minPath,?edge[nmax][nmax],?mark[nmax];//結(jié)點(diǎn)數(shù),邊數(shù),最小路徑,鄰接矩陣,結(jié)點(diǎn)訪問標(biāo)記????void?dfs(int?cur,?int?dst){????????/***operation***/????????????/***operation***/????????if(minPath?<?dst)?return;//當(dāng)前走過路徑大于之前最短路徑,沒必要再走下去????????if(cur?==?n){//臨界條件????????????if(minPath?>?dst)?minPath?=?dst;????????????return;????????}????????else{????????????int?i;????????????for(i?=?1;?i?<=?n;?i++){????????????????if(edge[cur][i]?!=?inf?&&?edge[cur][i]?!=?0?&&?mark[i]?==?0){????????????????????mark[i]?=?1;????????????????????dfs(i,?dst+edge[cur][i]);????????????????????mark[i]?=?0;????????????????????????????}????????????}????????????return;????????}????}????????int?main(){????????while(cin?>>?n?>>?m?&&?n?!=?0){????????????//初始化鄰接矩陣????????????int?i,?j;????????????for(i?=?1;?i?<=?n;?i++){????????????????for(j?=?1;?j?<=?n;?j++){????????????????????edge[i][j]?=?inf;????????????????}????????????????edge[i][i]?=?0;????????????}????????????int?a,?b;????????????while(m--){????????????????cin?>>?a?>>?b;????????????????cin?>>?edge[a][b];????????????}????????????//以dnf(1)為起點(diǎn)開始遞歸遍歷????????????memset(mark,?0,?sizeof(mark));????????????minPath?=?inf;????????????mark[1]?=?1;????????????dfs(1,?0);????????????cout?<<?minPath?<<?endl;????????}????????return?0;????}????
程序運(yùn)行結(jié)果如下:
?
?
2),弗洛伊德算法(解決多源最短路徑):時(shí)間復(fù)雜度O(n^3),空間復(fù)雜度O(n^2)
基本思想:最開始只允許經(jīng)過1號(hào)頂點(diǎn)進(jìn)行中轉(zhuǎn),接下來只允許經(jīng)過1號(hào)和2號(hào)頂點(diǎn)進(jìn)行中轉(zhuǎn)......允許經(jīng)過1~n號(hào)所有頂點(diǎn)進(jìn)行中轉(zhuǎn),來不斷動(dòng)態(tài)更新任意兩點(diǎn)之間的最短路程。即求從i號(hào)頂點(diǎn)到j(luò)號(hào)頂點(diǎn)只經(jīng)過前k號(hào)點(diǎn)的最短路程。
分析如下:1,首先構(gòu)建鄰接矩陣Floyd[n+1][n+1],假如現(xiàn)在只允許經(jīng)過1號(hào)結(jié)點(diǎn),求任意兩點(diǎn)間的最短路程,很顯然Floyd[i][j] = min{Floyd[i][j], Floyd[i][1]+Floyd[1][j]},代碼如下:
?
[cpp]?view plain?copy
for(i?=?1;?i?<=?n;?i++){??????for(j?=?1;?j?<=?n;?j++){??????????if(Floyd[i][j]?>?Floyd[i][1]?+?Floyd[1][j])??????????????Floyd[i][j]?=?Floyd[i][1]?+?Floyd[1][j];??????}??}??
2,接下來繼續(xù)求在只允許經(jīng)過1和2號(hào)兩個(gè)頂點(diǎn)的情況下任意兩點(diǎn)之間的最短距離,在已經(jīng)實(shí)現(xiàn)了從i號(hào)頂點(diǎn)到j(luò)號(hào)頂點(diǎn)只經(jīng)過前1號(hào)點(diǎn)的最短路程的前提下,現(xiàn)在再插入第2號(hào)結(jié)點(diǎn),來看看能不能更新更短路徑,故只需在步驟1求得的Floyd[n+1][n+1]基礎(chǔ)上,進(jìn)行Floyd[i][j] = min{Floyd[i][j], Floyd[i][2]+Floyd[2][j]};......
3,很顯然,需要n次這樣的更新,表示依次插入了1號(hào),2號(hào)......n號(hào)結(jié)點(diǎn),最后求得的Floyd[n+1][n+1]是從i號(hào)頂點(diǎn)到j(luò)號(hào)頂點(diǎn)只經(jīng)過前n號(hào)點(diǎn)的最短路程。故核心代碼如下:
?
[cpp]?view plain?copy
#define?inf?99999999??for(k?=?1;?k?<=?n;?k++){??????for(i?=?1;?i?<=?n;?i++){??????????for(j?=?1;?j?<=?n;?j++){??????????????if(Floyd[i][k]?<?inf?&&?Floyd[k][j]?<?inf?&&?Floyd[i][j]?>?Floyd[i][k]?+?Floyd[k][j])??????????????????Floyd[i][j]?=?Floyd[i][k]?+?Floyd[k][j];??????????}??????}??}??
例1:尋找最短的從商店到賽場(chǎng)的路線。其中商店在1號(hào)結(jié)點(diǎn)處,賽場(chǎng)在n號(hào)結(jié)點(diǎn)處,1~n結(jié)點(diǎn)中有m條線路雙向連接。
?
[cpp]?view plain?copy
/***先輸入n,m,再輸入m個(gè)三元組,n為路口數(shù),m表示有幾條路其中1為商店,n為賽場(chǎng),三元組分別表起點(diǎn),終點(diǎn),該路徑長(zhǎng),輸出1到n的最短路徑***/??#include?<iostream>??using?namespace?std;??#define?inf?99999999??#define?nmax?110??int?edge[nmax][nmax],?n,?m;??int?main(){??????while(cin?>>?n?>>?m?&&?n!=?0){??????????//構(gòu)建鄰接矩陣??????????int?i,?j;??????????for(i?=?1;?i?<=?n;?i++){??????????????for(j?=?1;?j?<=?n;?j++){??????????????????edge[i][j]?=?inf;??????????????}??????????????edge[i][i]?=?0;??????????}??????????while(m--){??????????????cin?>>?i?>>?j;??????????????cin?>>?edge[i][j];??????????????edge[j][i]?=?edge[i][j];??????????}??????????//使用弗洛伊德算法??????????int?k;??????????for(k?=?1;?k?<=?n;?k++){??????????????for(i?=?1;?i?<=?n;?i++){??????????????????for(j?=?1;?j?<=?n;?j++){??????????????????????if(edge[i][k]?<?inf?&&?edge[k][j]?<?inf?&&?edge[i][j]?>?edge[i][k]?+?edge[k][j])??????????????????????????edge[i][j]?=?edge[i][k]?+?edge[k][j];??????????????????}??????????????}??????????}??????????cout?<<?edge[1][n]?<<?endl;??????}??????return?0;??}??
程序運(yùn)行結(jié)果如下:
?
?
3),迪杰斯特拉算法(解決單源最短路徑)
基本思想:每次找到離源點(diǎn)(如1號(hào)結(jié)點(diǎn))最近的一個(gè)頂點(diǎn),然后以該頂點(diǎn)為中心進(jìn)行擴(kuò)展,最終得到源點(diǎn)到其余所有點(diǎn)的最短路徑。
基本步驟:1,設(shè)置標(biāo)記數(shù)組book[]:將所有的頂點(diǎn)分為兩部分,已知最短路徑的頂點(diǎn)集合P和未知最短路徑的頂點(diǎn)集合Q,很顯然最開始集合P只有源點(diǎn)一個(gè)頂點(diǎn)。book[i]為1表示在集合P中;
2,設(shè)置最短路徑數(shù)組dst[]并不斷更新:初始狀態(tài)下,令dst[i] = edge[s][i](s為源點(diǎn),edge為鄰接矩陣),很顯然此時(shí)dst[s]=0,book[s]=1。此時(shí),在集合Q中可選擇一個(gè)離源點(diǎn)s最近的頂點(diǎn)u加入到P中。并依據(jù)以u(píng)為新的中心點(diǎn),對(duì)每一條邊進(jìn)行松弛操作(松弛是指由結(jié)點(diǎn)s-->j的途中可以經(jīng)過點(diǎn)u,并令dst[j]=min{dst[j], dst[u]+edge[u][j]}),并令book[u]=1;
3,在集合Q中再次選擇一個(gè)離源點(diǎn)s最近的頂點(diǎn)v加入到P中。并依據(jù)v為新的中心點(diǎn),對(duì)每一條邊進(jìn)行松弛操作(即dst[j]=min{dst[j], dst[v]+edge[v][j]}),并令book[v]=1;
4,重復(fù)3,直至集合Q為空。
以下是圖示:
核心代碼如下所示:
?
[cpp]?view plain?copy
#define?inf?99999999??/***構(gòu)建鄰接矩陣edge[][],且1為源點(diǎn)***/??for(i?=?1;?i?<=?n;?i++)?dst[i]?=?edge[1][s];??for(i?=?1;?i?<=?n;?i++)?book[i]?=?0;??book[1]?=?1;??for(i?=?1;?i?<=?n-1;?i++){??????//找到離源點(diǎn)最近的頂點(diǎn)u,稱它為新中心點(diǎn)??????min?=?inf;??????for(j?=?1;?j?<=?n;?j++){??????????if(book[j]?==?0?&&?dst[j]?<?min){??????????????min?=?dst[j];??????????????u?=?j;??????????}??????}??????book[u]?=?1;??????//更新最短路徑數(shù)組??????for(k?=?1;?k?<=?n;?k++){??????????if(edge[u][k]?<?inf?&&?book[k]?==?0){??????????????if(dst[k]?>?dst[u]?+?edge[u][k])??????????????????dst[k]?=?dst[u]?+?edge[u][k];?????????????????????}??????}??}??
例1:給你n個(gè)點(diǎn),m條無向邊,每條邊都有長(zhǎng)度d和花費(fèi)p,給你起點(diǎn)s,終點(diǎn)t,要求輸出起點(diǎn)到終點(diǎn)的最短距離及其花費(fèi),如果最短距離有多條路線,則輸出花費(fèi)最少的。
輸入:輸入n,m,點(diǎn)的編號(hào)是1~n,然后是m行,每行4個(gè)數(shù) a,b,d,p,表示a和b之間有一條邊,且其長(zhǎng)度為d,花費(fèi)為p。最后一行是兩個(gè)數(shù)s,t;起點(diǎn)s,終點(diǎn) t。n和m為 0 時(shí)輸入結(jié)束。(1<n<=1000, 0<m<100000, s != t)
輸出:輸出一行,有兩個(gè)數(shù), 最短距離及其花費(fèi)。
分析:由于每條邊有長(zhǎng)度d和花費(fèi)p,最好構(gòu)建邊結(jié)構(gòu)體存放,此外可以使用鄰接鏈表,使用鄰接鏈表時(shí)需要將上面的核心代碼修改幾個(gè)地方:
1,初始化dst[]時(shí)使用結(jié)點(diǎn)1的鄰接鏈表;
2,更新最短路徑數(shù)組時(shí),k的范圍由1~n變?yōu)?~edge[u].size()。先采用鄰接矩陣解決此題,再使用鄰接表解決此題,兩種方法的思路都一樣:初始化鄰接矩陣或鄰接鏈表,并
初始化最短路徑數(shù)組dst ----> n-1輪邊的松弛中,先找到離新源點(diǎn)最近的中心點(diǎn)u,之后根據(jù)中心點(diǎn)u為轉(zhuǎn)折點(diǎn)來更新路徑數(shù)組。
使用鄰接矩陣求解:
?
[cpp]?view plain?copy
/***對(duì)于無向圖,輸入n,m,點(diǎn)的編號(hào)是1~n,然后是m行,每行4個(gè)數(shù)?a,b,d,p,表示a和b之間有一條邊,且其長(zhǎng)度為d,花費(fèi)為p。最后一行是兩個(gè)數(shù)s,t;起點(diǎn)s,終點(diǎn)?t。***/??/***n和m為?0?時(shí)輸入結(jié)束。(1<n<=1000,?0<m<100000,?s?!=?t)?????輸出:輸出一行,有兩個(gè)數(shù),?最短距離及其花費(fèi)。***/??#include?<iostream>??#include?<iomanip>??using?namespace?std;??#define?nmax?1001??#define?inf?99999999??struct?Edge{??????int?len;??????int?cost;??};??Edge?edge[nmax][nmax];??int?dst[nmax],?spend[nmax],?book[nmax],?n,?m,?stNode,?enNode;??int?main(){??????while(cin?>>?n?>>?m?&&?n?!=?0?&&?m?!=?0){??????????int?a,?b,?i,?j;??????????//構(gòu)建鄰接矩陣和最短路徑數(shù)組??????????for(i?=?1;?i?<=?n;?i++){??????????????for(j?=?1;?j?<=?n;?j++){??????????????????edge[i][j].cost?=?0;??????????????????edge[i][j].len?=?inf;??????????????}??????????????edge[i][i].len?=?0;??????????}??????????while(m--){??????????????cin?>>?a?>>?b;??????????????cin?>>?edge[a][b].len?>>?edge[a][b].cost;??????????????edge[b][a].len?=?edge[a][b].len;??????????????edge[b][a].cost?=?edge[a][b].cost;??????????}??????????cin?>>?stNode?>>?enNode;??????????for(i?=?1;?i?<=?n;?i++){??????????????dst[i]?=?edge[stNode][i].len;??????????????spend[i]?=?edge[stNode][i].cost;??????????}??????????memset(book,?0,?sizeof(book));??????????book[stNode]?=?1;??????????//開始迪杰斯特拉算法,進(jìn)行剩余n-1次松弛??????????int?k;??????????for(k?=?1;?k?<=?n-1;?k++){??????????????//找離源點(diǎn)最近的頂點(diǎn)u??????????????int?minNode,?min?=?inf;??????????????for(i?=?1;?i?<=?n;?i++){??????????????????if(book[i]?==?0?&&?min?>?dst[i]?/*?||?min?==?dst[i]&&?edge[stNode][min].cost?>?edge[stNode][i].cost*/){??????????????????????min?=?dst[i];??????????????????????minNode?=?i;??????????????????}??????????????}??????????????//cout?<<?setw(2)?<<?minNode;??????????????book[minNode]?=?1;//易錯(cuò)點(diǎn)1,錯(cuò)寫成book[i]=1??????????????//以中心點(diǎn)u為轉(zhuǎn)折點(diǎn)來更新路徑數(shù)組和花費(fèi)數(shù)組??????????????for(i?=?1;?i?<=?n;?i++){??????????????????if(book[i]?==?0?&&?dst[i]?>?dst[minNode]?+?edge[minNode][i].len?||?dst[i]?==?dst[minNode]?+?edge[minNode][i].len?&&?spend[i]?>?spend[minNode]?+?edge[minNode][i].cost){??????????????????????dst[i]?=?dst[minNode]?+?edge[minNode][i].len;//易錯(cuò)點(diǎn)2,錯(cuò)寫成dst[i]+??????????????????????spend[i]?=?spend[minNode]?+?edge[minNode][i].cost;??????????????????}??????????????}??????????}??????????cout?<<?dst[enNode]?<<?setw(3)?<<?spend[enNode]?<<?endl;??????}??????return?0;??}??
程序運(yùn)行結(jié)果如下:
使用鄰接鏈表求解:
?
[cpp]?view plain?copy
/***對(duì)于無向圖,輸入n,m,點(diǎn)的編號(hào)是1~n,然后是m行,每行4個(gè)數(shù)?a,b,d,p,表示a和b之間有一條邊,且其長(zhǎng)度為d,花費(fèi)為p。最后一行是兩個(gè)數(shù)s,t;起點(diǎn)s,終點(diǎn)?t。***/??/***n和m為?0?時(shí)輸入結(jié)束。(1<n<=1000,?0<m<100000,?s?!=?t)?????輸出:輸出一行,有兩個(gè)數(shù),?最短距離及其花費(fèi)。***/??#include?<iostream>??#include?<iomanip>??#include?<vector>??using?namespace?std;??#define?nmax?1001??#define?inf?99999999??struct?Edge{??????int?len;??????int?cost;??????int?next;??};??vector<Edge>?edge[nmax];??int?dst[nmax],?spend[nmax],?book[nmax],?n,?m,?stNode,?enNode;??int?main(){??????while(cin?>>?n?>>?m?&&?n?!=?0?&&?m?!=?0){??????????int?a,?b,?i,?j;??????????//構(gòu)建鄰接表和最短路徑數(shù)組??????????for(i?=?1;?i?<=?n;?i++)?edge[i].clear();??????????while(m--){??????????????Edge?tmp;??????????????cin?>>?a?>>?b;??????????????tmp.next?=?b;??????????????cin?>>?tmp.len?>>?tmp.cost;??????????????edge[a].push_back(tmp);??????????????tmp.next?=?a;??????????????edge[b].push_back(tmp);??????????}??????????cin?>>?stNode?>>?enNode;??????????for(i?=?1;?i?<=?n;?i++)?dst[i]?=?inf;?//注意2,別忘記寫此句來初始化dst[]??????????for(i?=?0;?i?<?edge[stNode].size();?i++){//注意1,從下標(biāo)0開始存元素,誤寫成i?<=?edge[stNode].size()??????????????dst[edge[stNode][i].next]?=?edge[stNode][i].len;??????????????//cout?<<?dst[2]?<<?endl;??????????????spend[edge[stNode][i].next]?=?edge[stNode][i].cost;??????????}??????????memset(book,?0,?sizeof(book));??????????book[stNode]?=?1;??????????//開始迪杰斯特拉算法,進(jìn)行剩余n-1次松弛??????????int?k;??????????for(k?=?1;?k?<=?n-1;?k++){??????????????//找離源點(diǎn)最近的頂點(diǎn)u??????????????int?minnode,?min?=?inf;??????????????for(i?=?1;?i?<=?n;?i++){??????????????????if(book[i]?==?0?&&?min?>?dst[i]?/*?||?min?==?dst[i]&&?edge[stnode][min].cost?>?edge[stnode][i].cost*/){??????????????????????min?=?dst[i];??????????????????????minnode?=?i;??????????????????}??????????????}??????????????//cout?<<?setw(2)?<<?minnode;??????????????book[minnode]?=?1;//易錯(cuò)點(diǎn)1,錯(cuò)寫成book[i]=1??????????????//以中心點(diǎn)u為轉(zhuǎn)折點(diǎn)來更新路徑數(shù)組和花費(fèi)數(shù)組??????????????for(i?=?0;?i?<?edge[minnode].size();?i++){??????????????????int?t?=?edge[minnode][i].next;//別忘了加此句,表示與結(jié)點(diǎn)minnode相鄰的點(diǎn)??????????????????if(book[t]?==?0?&&?dst[t]?>?dst[minnode]?+?edge[minnode][i].len?||?dst[t]?==?dst[minnode]?+?edge[minnode][i].len?&&?spend[t]?>?spend[minnode]?+?edge[minnode][i].cost){??????????????????????dst[t]?=?dst[minnode]?+?edge[minnode][i].len;??????????????????????spend[t]?=?spend[minnode]?+?edge[minnode][i].cost;??????????????????}??????????????}??????????}??????????cout?<<?dst[enNode]?<<?setw(3)?<<?spend[enNode]?<<?endl;??????}??????return?0;??}??
程序運(yùn)行結(jié)果如下:
使用鄰接表時(shí),注意更新dst[],book[]時(shí)要使用鄰接表元素對(duì)應(yīng)下標(biāo)中的next成員,而涉及到權(quán)值加減時(shí)時(shí)需要使用鄰接表中的對(duì)應(yīng)下標(biāo)來取得權(quán)值;而使用鄰接矩陣就沒這么多顧慮了,因?yàn)檫@時(shí)候鄰接矩陣對(duì)應(yīng)下標(biāo)和dst[]要更新元素的下標(biāo)正好一致,都是從1開始編號(hào)。
?
?
4),Bellman-Ford算法(解決負(fù)權(quán)邊,解決單源最短路徑,前幾種方法不能求含負(fù)權(quán)邊的圖)::時(shí)間復(fù)雜度O(nm),空間復(fù)雜度O(m)
主要思想:對(duì)所有的邊進(jìn)行n-1輪松弛操作,因?yàn)樵谝粋€(gè)含有n個(gè)頂點(diǎn)的圖中,任意兩點(diǎn)之間的最短路徑最多包含n-1邊。換句話說,第1輪在對(duì)所有的邊進(jìn)行松弛后,得到的是從1號(hào)頂點(diǎn)只能經(jīng)過一條邊到達(dá)其余各定點(diǎn)的最短路徑長(zhǎng)度。第2輪在對(duì)所有的邊進(jìn)行松弛后,得到的是從1號(hào)頂點(diǎn)只能經(jīng)過兩條邊到達(dá)其余各定點(diǎn)的最短路徑長(zhǎng)度,......
以下是圖示:
此外,Bellman_Ford還可以檢測(cè)一個(gè)圖是否含有負(fù)權(quán)回路:如果在進(jìn)行n-1輪松弛后仍然存在dst[e[i]] > dst[s[i]]+w[i]。算法核心代碼如下:
?
[cpp]?view plain?copy
#define?inf?999999999??for(i?=?1;?i?<=?n;?i++)?dst[i]?=?inf;??dst[1]?=?0;??for(k?=?1;?k?<=?n-1;?k++){??????for(i?=?1;?i?<=?m;?i++){??????????if(dst[e[i]]?>?dst[s[i]]?+?w[i])??????????????dst[e[i]]?=?dst[s[i]]?+?w[i];??????}??}??//檢測(cè)負(fù)權(quán)回路??flag?=?0;??for(i?=?1;?i?<=?m;?i++){??????if(dst[e[i]]?>?dst[s[i]]?+?w[i])??????????flag?=?1;??}??if(flag)?cout?<<?"此圖含有負(fù)權(quán)回路";??
例1:對(duì)圖示中含負(fù)權(quán)的有向圖,輸出從結(jié)點(diǎn)1到各結(jié)點(diǎn)的最短路徑,并判斷有無負(fù)權(quán)回路。
?
[cpp]?view plain?copy
/***先輸入n,m,分別表結(jié)點(diǎn)數(shù)和邊數(shù),之后輸入m個(gè)三元組,各表起點(diǎn),終點(diǎn),邊權(quán),輸出1號(hào)結(jié)點(diǎn)到各結(jié)點(diǎn)的最短路徑****/??#include?<iostream>??#include?<iomanip>??using?namespace?std;??#define?nmax?1001??#define?inf?99999999??int?n,?m,?s[nmax],?e[nmax],?w[nmax],?dst[nmax];??int?main(){??????while(cin?>>?n?>>?m?&&?n?!=?0?&&?m?!=?0){??????????int?i,?j;??????????//初始化三個(gè)數(shù)組:起點(diǎn)數(shù)組s[],終點(diǎn)數(shù)組e[],權(quán)值數(shù)組w[],最短路徑數(shù)組dst[]??????????for(i?=?1;?i?<=?m;?i++)??????????????cin?>>?s[i]?>>?e[i]?>>?w[i];??????????for(i?=?1;?i?<=?n;?i++)??????????????dst[i]?=?inf;??????????dst[1]?=?0;??????????//使用Bellman_Ford算法??????????for(j?=?1;?j?<=?n-1;?j++){??????????????for(i?=?1;?i?<=?m;?i++){??????????????????if(dst[e[i]]?>?dst[s[i]]?+?w[i])??????????????????????dst[e[i]]?=?dst[s[i]]?+?w[i];??????????????}??????????}??????????//測(cè)試是否有負(fù)權(quán)回路并輸出??????????int?flag?=?0;??????????for(i?=?1;?i?<=?m;?i++)??????????????if(dst[e[i]]?>?dst[s[i]]?+?w[i])??????????????????flag?=?1;??????????if(flag)?cout?<<?"此圖含有負(fù)權(quán)回路\n";??????????else{??????????????for(i?=?1;?i?<=?n;?i++){??????????????????if(i?==?1)??????????????????????cout?<<?dst[i];??????????????????else???????????????????????cout?<<?setw(3)?<<?dst[i];??????????????}??????????????cout?<<?endl;??????????}??????}??????return?0;??}??
程序運(yùn)行結(jié)果如下:
總結(jié)
以上是生活随笔為你收集整理的图的四种最短路径算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。