求解所有兩點間的最短路的問題叫做任意兩點間的最短路問題。讓我們試著用dp來求解任意兩點間的最短路問題。只使用0~k的情況下,記i到j的最短路長度為d[k+1][i][j]。k=-1時,認為只使用i和j,所以d[0][i][j]=cost[i][j]。接下來讓我們把只使用頂點0~k的問題歸納到只使用0~k-1的問題上。
只使用0~k時,我們分i到j的最短路正好經過頂點k和完全不經過頂點k兩種情況來討論。不經過頂點k的情況下,d[k][i][j]=d[k-1][i][j]。通過頂點k的情況下,d[k][i][j]=d[k-1][i][k]+d[k-1][k][j]。合起來,就得到了d[k][i][j]=min(d[k-1][i][k],d[k-1][k][j])。這個dp也可以使用同乙個陣列,不斷進行d[i][j]=min(d[i][j],d[i][k]+d[k][j])的更新來實現。
這個演算法叫做floyd-warshall演算法,可以在o(|v|3
)時間裡求得所有兩點間的最短長度。floyd-warshall演算法和bellman-ford演算法一樣,可以處理邊是負數的情況。而判斷圖中是否有負圈,只需要檢查是否存在d[i][i]是負數的頂點i就可以了。
#include#include#includeconst int max_n=1100;
const int inf=0x3f3f3f3f;
using namespace std;
int n,m;
int d[max_n][max_n],path[max_n][max_n];
int main()
int a,b,c;
for(int i=1;i<=m;i++)
for(int k=1;k<=n;k++) //floyd演算法
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
printf("%d\n",ed);
// for(int i=1;i<=n;i++)
return 0;
}
floyd演算法的具體實現過程,參見: 任意兩點間的最短路 Floyd及其本質
我們知道在已知起點的情況下,求到其他任何一點的最短路是用dijkstra,那麼在乙個有向圖中,我們想知道任意兩點之間的最短路,我們就可以使用floyd,而且這個演算法表面看起來非常的簡單,就是乙個三重迴圈,如果這個圖有n個點,那麼複雜度為o n 3 如下。1 for int k 0 k 2for i...
兩點間的距離 floyd演算法
floyd演算法求任意兩點間的最短距離,本質是動態規劃。d k,i,j 表示 進過若干個編號不超過k的節點 從i到j的最短路徑長度 該問題可以劃分為兩個子問題 經過編號不超過k 1的節點從i到j,過或先從i到k再到j,d k,i,j min d k 1,i,j d k 1,i,k d k 1,k,j...
Dijstra求任意兩點間最短路徑並輸出
用迪傑斯特拉演算法求一點到其餘所有結點的最短路徑。先輸入乙個小於100的正整數n,然後輸入圖的鄰接矩陣 10000表示無窮大,即兩點之間沒有邊 最後輸入兩個0到n 1的整數表示兩個點。先用迪傑斯特拉演算法求給定的第乙個點到其餘所有結點的最短路徑。然後再輸出給定的兩個點之間的最短路徑 按順序輸出最短路...