C++的最短路徑的弗洛伊德算法案例講解
現(xiàn)在我們有這么一張圖:
我們要做的是求出從某一點(diǎn)到達(dá)任意一點(diǎn)的最短距離,我們先用鄰接矩陣來(lái)建圖,map[i][j]表示從i點(diǎn)到j(luò)點(diǎn)的距離,把自己到自己設(shè)為0,把自己到不了的邊初始化為無(wú)窮大,代碼為:
//初始化 for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(i==j) map[i][j]=0; else map[i][j]=inf; //讀入邊 for(int i=1; i<=m; i++) { scanf("%d%d%d",&t1,&t2,&t3); map[t1][t2]=t3; }
最后,建好的圖可以用表格來(lái)表示:
現(xiàn)在,我們來(lái)思考,假設(shè)我們來(lái)找一個(gè)中轉(zhuǎn)的點(diǎn),看他們的路程會(huì)不會(huì)改變,我們先以1號(hào)頂點(diǎn)作為中轉(zhuǎn)點(diǎn)最為例子,制圖:
我們發(fā)現(xiàn),圖有了變化,我們?cè)趺磁袛嘁?號(hào)頂點(diǎn)作為中轉(zhuǎn)點(diǎn)圖的路程是不是更短呢,我們只需要判斷map[i][1]+map[1][j]的路程是不是比map[i][j]的路程更短,就可以判斷,
代碼為:
for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(map[i][1]+map[1][j]<map[i][j]) map[i][j]=map[i][1]+map[1][j];
現(xiàn)在該怎么辦呢,我們接著以2號(hào)頂點(diǎn)作為中轉(zhuǎn)點(diǎn),很簡(jiǎn)單代碼修改一句就就可以:
for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(map[i][2]+map[2][j]<map[i][j]) map[i][j]=map[i][2]+map[2][j];
現(xiàn)在我們是不是發(fā)現(xiàn)了一個(gè)規(guī)律,只要不斷的遍歷每一個(gè)點(diǎn),并且以每一個(gè)點(diǎn)作為中轉(zhuǎn)點(diǎn)看看它的值會(huì)不會(huì)改變,就可以得到從一個(gè)點(diǎn)到任意一個(gè)點(diǎn)的最短路徑,也就是多源最短路,這就是弗洛伊德算法,代碼為:
for(int k=1; k<=n; k++) for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(map[i][k]+map[k][j]<map[i][j]) map[i][j]=map[i][k]+map[k][j];
這樣就可以遍歷每個(gè)頂點(diǎn),找出所有的最短路,算法的復(fù)雜度為O(n^3).
對(duì)于我一開(kāi)始提出的問(wèn)題,完整的代碼為:
#include <stdio.h> #include <string.h> #include <string> #include <iostream> #include <stack> #include <queue> #include <vector> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int inf=1<<29; int main() { int map[10][10],n,m,t1,t2,t3; scanf("%d%d",&n,&m);//n表示頂點(diǎn)個(gè)數(shù),m表示邊的條數(shù) //初始化 for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(i==j) map[i][j]=0; else map[i][j]=inf; //讀入邊 for(int i=1; i<=m; i++) { scanf("%d%d%d",&t1,&t2,&t3); map[t1][t2]=t3; } //弗洛伊德(Floyd)核心語(yǔ)句 for(int k=1; k<=n; k++) for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(map[i][k]+map[k][j]<map[i][j]) map[i][j]=map[i][k]+map[k][j]; for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) printf("%10d",map[i][j]); printf("\n"); } return 0; }
給出樣例:
輸入:
4 8 1 2 2 1 3 6 1 4 4 2 3 3 3 1 7 3 4 1 4 1 5 4 3 12
輸出:
0 2 5 4 9 0 3 4 6 8 0 1 5 7 10 0
輸出的就是我建圖的時(shí)候用的表格,可以表示任意一點(diǎn)到任意一點(diǎn)的最短距離。
如果有什么不對(duì)的地方,歡迎指正~~
到此這篇關(guān)于C++的最短路徑的弗洛伊德算法案例講解的文章就介紹到這了,更多相關(guān)C++的最短路徑的弗洛伊德算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言中操作utmp文件的相關(guān)函數(shù)用法
這篇文章主要介紹了C語(yǔ)言中操作utmp文件的相關(guān)函數(shù)用法,包括getutent()函數(shù)和setutent()函數(shù)以及endutent()函數(shù),需要的朋友可以參考下2015-08-08C++實(shí)現(xiàn)LeetCode(211.添加和查找單詞-數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì))
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(211.添加和查找單詞-數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08visual studio 2019工具里添加開(kāi)發(fā)中命令提示符的方法
這篇文章主要介紹了visual studio 2019工具里添加開(kāi)發(fā)中命令提示符的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03C語(yǔ)言實(shí)現(xiàn)外賣(mài)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)外賣(mài)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11Linux網(wǎng)絡(luò)編程之UDP Socket程序示例
這篇文章主要介紹了Linux網(wǎng)絡(luò)編程之UDP Socket程序示例,有助于讀者在實(shí)踐中掌握UDP協(xié)議的原理及應(yīng)用方法,需要的朋友可以參考下2014-08-08C/C++中CJSON的使用(創(chuàng)建與解析JSON數(shù)據(jù))
cJSON是一個(gè)超輕巧的JSON解析器,本文主要介紹了C/C++中CJSON的使用(創(chuàng)建與解析JSON數(shù)據(jù)),具有一定的參考價(jià)值,感興趣的可以了解一下2021-09-09