分有向圖和無向圖。算法
有向圖很簡單:直接建邊而後跑\(Floyd\),跑完之後,\(dis(i,i)\)就是通過\(i\)點的最小環的長度。數組
無向圖……就是在以\(k\)爲中間點擴展以前就把\(k\)拿進去統計spa
像這樣:code
for(int k=1;k<=n;k++) { for(int i=1;i<k;i++) for(int j=i+1;j<k;j++) minr=std::min( minr,dis[i][j]+e[i][k]+e[j][k] ); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j]=std::min( dis[i][j],dis[i][k]+dis[k][j] ); }
這個挺有意思。class
有這樣一個問題:求\(S\)到\(T\)通過\(k\)條邊的最短路。擴展
若是\(N\)可以接受\(O(n^3)\)的算法,那麼\(Floyd\)就派上用場了。im
若是\(A\)矩陣和\(B\)矩陣分別表示通過\(x\)條邊和\(y\)條邊的矩陣,那麼新的矩陣\(C=A\times B\)就是通過\(x+y\)條邊的矩陣。統計
JZ res; for(int i=1;i<=idx_cnt;i++) for(int s=1;s<=idx_cnt;s++) for(int t=1;t<=idx_cnt;t++) res.a[s][t]=std::min( res.a[s][t],a[s][i]+op.a[i][t] ); return res;
和普通的\(Floyd\)算法不一樣的是,在這裏,等式兩邊的矩陣是相互獨立的。也就是說,\(C\)矩陣中的\(dis\)不會對\(A\)和\(B\)當中的產生影響,因此\(C\)矩陣是切切實實只表示\(x+y\)條邊的矩陣。di
而\(Floyd\)算法中,用\(1\)條邊的信息統計完\(2\)條邊的信息以後,\(2\)條邊的信息又要立刻在\(dis\)數組裏面用來統計\(3\)條、\(4\)條邊的信息,因此不是獨立的。co
知道具體含義以後就能夠用矩陣快速冪了:-)