復習Floyd-Warshall算法


能在O(|V|^3)求出圖中任意兩點間的最短距離。

本質是一個dp,剛看這個算法時總感覺不能正確更新,因為當兩個點中間有好多點的時候,借助那個點的操作不能正常更新,可是仔細想想,每次枚舉中間點的時候,會更新與它相鄰的兩個點,感覺相當於縮點。。還可以想象,任何兩個點之間的最短距離都是借助某個中間點或者直接到達,這樣枚舉已經包含了所有的狀態,然而枚舉順序必須是先枚舉中間點,然后是兩個借助它的點,這是因為先枚舉兩邊的點就不會有更改的機會了。

代碼。

#include <iostream>
#include <cstdio>
#include <cstring>
#define INF 99999999
using namespace std;
const int maxn = 305;
int dp[maxn][maxn];
int V,E;
void floyd_warshall()
{
    for(int k=0;k<V;k++)
     for(int i=0;i<V;i++)
      for(int j=0;j<V;j++)
        dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);
}
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d%d",&V,&E);
    for(int i=0;i<V;i++)
    {
     for(int j=0;j<V;j++)
      dp[i][j]=INF;
     dp[i][i]=0;
    }
    for(int i=1;i<=E;i++)
    {
        int f,t,v;
        scanf("%d%d%d",&f,&t,&v);  //默認輸入下標從一開始
        dp[f-1][t-1]=v;
    }
    floyd_warshall();
    for(int i=0;i<V;i++)
     for(int j=0;j<V;j++)
      printf("%d->%d:%d\n",i+1,j+1,dp[i][j]);
    return 0;
}



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com