對dijkstra和Floyd演算法的理解
阿新 • • 發佈:2019-02-10
演算法的適應範圍
Floyed 演算法:
弗洛伊德演算法是解決任意兩點間的最短路徑的一種演算法,可以正確處理無向圖或有向圖或負權(但不可存在負權迴路)的最短路徑問題,同時也被用於計算有向圖的傳遞閉包。
Floyed演算法允許圖中有帶負權值邊,允許有迴路,但不允許有帶負權值邊的迴路。
Dijkstra演算法:
Dijkstra演算法只適用於正權圖的單源最短路。而對於存在權值為負的邊的圖,我們用的是SPFA(Shortest Path Faster Algorithm)演算法(佇列優化後的Bellman-Ford)。
ps:含負權的圖中最短路不一定存在。顯而易見,若一個圖中存在一個負環
演算法的具體操作
用演算法之前的建圖二者是一樣的,首先對map[][]進行初始化
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j]=(i==j?0:INF);
如果路是雙向的,就賦值map[i][j]=map[j][i]=權值,如果路是單向的,就賦值map[i][j]=權值。
Dijkstra演算法:
這個演算法和求最小生成樹的prim演算法很像(對prim演算法的理解 ),唯一不同的就是對距離陣列dis的更新。
dis[i]:x到n的最短路的距離。
void dijkstra(int x) { int i,j; for(i=1;i<=n;i++) dis[i]=map[x][i]; vis[x]=0; for(i=1;i<=n;i++) { int min=INF; int temp; for(j=1;j<=n;j++) if(vis[j]&&dis[j]<min) { min=dis[j]; temp=j; } vis[temp]=0; for(j=1;j<=n;j++) if(vis[j]&&dis[temp]+map[temp][j]<dis[j]) dis[j]=dis[temp]+map[temp][j]; } }
Floyd演算法:
map[i][j]:i到j的最短路的距離。
void floyd()
{
int i,j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i!=k&&i!=j&&k!=j)
map[i][j]=minn(map[i][j],map[i][k]+map[k][j]);
}