標籤:void def 時間 turn blog a演算法 include 作用 一點
如題,這是最短路演算法Floyd。
Floyd,是只有五行的代碼。
簡單,易懂。O(N的三方)的時間也可以。
遇到簡單的就這麼用。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<queue>#define s(q) scanf("%d",&q)#define p(q) printf("%d",q)#define pk(q) printf(" %d",q)#define pp printf("\n")#define lp(q) printf("%lld",q)#define r(q) return q;#define ffor(i,l,k) for(i=l;i<=k;i++)using namespace std;int n,i,j,k;int a[101][101];void Floyd(){ ffor(i,1,n) ffor(j,1,n) ffor(k,1,n) if(a[i][j]>a[k][j]+a[i][k] && a[k][j]+a[i][k]>0) a[i][j]=a[k][j]+a[i][k];}int main(){ s(n); ffor(i,1,n) ffor(j,1,n) s(a[i][j]); Floyd(); /*ffor(i,1,n){ ffor(j,1,n){ pk(a[i][j]); }pp; }*/ r(0);}
這一條是不是很簡單?
Floyd的作用就是幫你尋找兩個點的最短路,就是:
如果i點到j點的路線大於i點到k點,然後再轉到j點的路線,那麼你就可以將i點到j點的路線替換為i點到k點,然後再轉到j點的路線。
如果說兩條邊不能通,設為正無窮也可以。
我的輸入可以改成:
現將所有的點與點的邊變為正無窮,然後在輸入某一點到另一點的,更新資料,再Floyd。
注意:要找到不能找為止!
值得一提的是,Floyd並不能“負權迴路”,因為這種東西沒有最短路。
就像這樣:1->2->3->1->2......1->2->3......每一次迴圈最短路就會減少1,永遠找不到。
如果要快,可以用Dijkstra演算法(空間複雜度O(M),時間複雜度O(M+N)logN)以及Bellman-Ford及其最佳化(空間複雜度O(M),時間複雜度O(NM)或最壞O(NM))
額,Floyd空間複雜度是O(N的2方),時間複雜度是O(N的3方)。
如果你看不清楚上面的Floyd就看下面這個沒有#define的。
void Floyd(){ for(i=1;i<=n;i++) for(j=1;j<=n;j++) for(k=1;k<=n;k++) if(a[i][j]>a[k][j]+a[i][k] && a[k][j]+a[i][k]>0) a[i][j]=a[k][j]+a[i][k];}
應該沒有人不知道a[i][j]幹什麼吧?
a是用來貯存最短路的。
Floyd演算法(最短路)