Floyd是用於查找圖中每一對頂點之間的最短距離,是以動態規劃爲基礎的算法;ios
基本思想:若如今要求vi到vj的最短路徑,設vi到vj的路徑dis(vi,vj)即爲最短路徑,可將dis(vi,vj)與dis(vi,v0,vj)進行比較(其中v0表示vi到vj之間的一個結點,即vi能經過v0到達vj),取較小值,而後在此較小值上再增長一個結點v1,將dis(vi,...,v1,...,vj)和已經獲得的從vi到vj的較小值比較,取較小值;再增長一個結點v2,以此類推,最終即可獲得vi到vj的最短路徑。算法
由上述可得出遞推公式(arc表示i到j的直接路徑,若沒有,用一個極大值0x3f3f3f3f代替):spa
上代碼:3d
void floyd(int n){ for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(a[i][k]+a[k][j]<a[i][j]){ a[i][j] = a[i][k]+a[k][j]; } } } } }
接下來上一個例題,poj1125.code
題目描述:炒股爲了得到高收益,投資人須要釋放謠言引發恐慌,投資人目前有幾個手下專門用於釋放謠言,最後要使得他們都知道這個謠言,要求輸入這幾個手下之間互相傳遞信息的時間,信息可同時傳遞,輸出使他們都知道消息的最短期方案(以誰爲消息源,時間是多少).blog
輸入:ci
包含多個輸入樣例,以0結束,開頭輸入一個n表示n個手下,接下來輸入n行,每行開頭輸入一個m表示這個手下與多少我的有聯繫,緊接着輸入m組數據表示這個手下與哪一個手下有聯繫以及傳播時間string
輸出:io
消息源手下編號,最短期class
樣例輸入:
3 2 2 4 3 5 2 1 2 3 6 2 1 2 2 2 5 3 4 4 2 8 5 3 1 5 8 4 1 6 4 10 2 7 5 2 0 2 2 5 1 5 0
樣例輸出:
3 2 3 10
分析:很明顯此題要求的是,從一個結點出發到其餘全部結點的最短路徑,且可在同一時間進行傳播,那麼首先要用floyd求出每一個結點之間的最短路徑,
因爲可在同一時間進行傳播這一條件,最終的完成時間確定是這個結點到其餘節點最短路徑的最大值,那麼只需找出這些對大體當中的最小值即是最短期,並記錄對應下標即是消息源
代碼以下:
#include<iostream> #include<cstring> using namespace std; const int MAX = 0x3f3f3f3f; int a[105][105]; /* poj 1125 floyd算法 */ void floyd(int n){ for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(a[i][k]+a[k][j]<a[i][j]){ a[i][j] = a[i][k]+a[k][j]; } } } } } int main(){ int n; int res; while(cin>>n,n!=0){ int min=0x3f3f3f3f; memset(a,MAX,sizeof(a)); for(int i=1;i<=n;i++){ int m; cin>>m; for(int j=0;j<m;j++){ int temp; cin>>temp; cin>>a[i][temp]; } } floyd(n); for(int i=1;i<=n;i++){ int max=0; for(int j=1;j<=n;j++){ if(i==j) continue; if(a[i][j]>max){ max=a[i][j]; } } if(max<min){ min=max; res=i; } } cout<<res<<" "<<min<<endl; // for(int i=1;i<=n;i++){ // for(int j=1;j<=n;j++){ // cout<<a[i][j]<<" "; // } // cout<<endl; // } } return 0; }