最短路之——弗洛伊德演算法(floyd)
阿新 • • 發佈:2019-02-20
來源: https://blog.csdn.net/riba2534/article/details/54562440
我們要做的是求出從某一點到達任意一點的最短距離,我們先用鄰接矩陣來建圖,map[i][j]表示從i點到j點的距離,把自己到自己設為0,把自己到不了的邊初始化為無窮大,程式碼為:
- //初始化
- 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;
- }
現在,我們來思考,假設我們來找一箇中轉的點,看他們的路程會不會改變,我們先以1號頂點作為中轉點最為例子,製圖:
我們發現,圖有了變化,我們怎麼判斷以1號頂點作為中轉點圖的路程是不是更短呢,我們只需要判斷map[i][1]+map[1][j]的路程是不是比map[i][j]的路程更短,就可以判斷,
程式碼為:
- for(
- 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];
- 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];
- 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];
對於我一開始提出的問題,完整的程式碼為:
- #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))
- usingnamespace std;
- constint inf=1<<29;
- int main()
- {
- int map[10][10],n,m,t1,t2,t3;
- scanf("%d%d",&n,&m);//n表示頂點個數,m表示邊的條數
- //初始化
- 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)核心語句
- 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;
- }