求全图的所有最短路径-floyd算法(弗洛伊德算法)

如果需要求出每两点之间的最短路,不必调用n次Dijkstra(边权均为正)或者bellman-ford(有负权)。有一个更简单的方法可以实现——Floyd-Warshall算法,以下代码熟记即可,即i到j的最短路径,是i到j的直连或者通过任意k中转的最短路径

for(int k=0;k<n;k++)
      for(int i=0;i<n;i++)
              for(int j=0;j<n;j++)
                     d[i][j] = min(d[i][j], d[i][k] + d[k][j]);

在调用它之前只需做一些简单的初始化: d[i][i] = 0, 其他d值为INT_MAX/2。注意这里有一个潜在的问题:如果d初始值定义太大,加法d[i][k] + d[k][j]可能会溢出。

如果d初始值太小,可能会使得长度为d的边真的变成最短路的一部分。例如, 最多有1000条边,每边<1000,那么d的初始值可以为1000001。

在有向图中,有时不必关心路径的长度,而只关心每两点间是否有通路,则可以用1和0分别表示“连通”和“不连通”。这样,除了预处理需做少许调整外,主算法中只需把“d[i][j]=min{d[i][j], d[i][k]+d[k][j]}”改成“d[i][j]=d[i][j]||(d[i][k]&&d[k][j])”。这样的结果称为有向图的传递闭包(transitive closure)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章