點對間的最短路 Floyd-Warshall

最近把Floyd算法看了幾遍以後算是明白了一些。感覺Floyd算法本質上是DP,自底向上求出任意點對間的最短路。使用DP[k][i][j]表示中間點可能爲0~k的i到j的最短路。然後對k進行考察。一種情況是k存在於i到j的最短路徑上,i~k~j。另一種則是k不在i到j的最短路徑上。轉移方程爲DP[k][i][j]=min(DP[k][i][j],DP[k-1][i][k]+DP[k-1][k][j])。在實現的過程中可以使用一個二維數組來完成。


#include<bits/stdc++.h>
#define INF 0x3f3f3f
using namespace std;

int dp[105][105];

bool solve(int v)
{
    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][k]+dp[k][j] , dp[i][j]);
            }
        }
    }
    for (int i=0 ; i<v ; i++)
    {
        if (dp[i][i]<0)
            return 0;
    }
    return 1;
}


int main()
{
    int n,m;
    while (cin>>n>>m)
    {
        for (int i=0 ; i<105 ; i++)
            for (int j=0 ; j<105 ; j++)
            {
                if (i != j)
                    dp[i][j] = INF;
                else
                    dp[i][j] = 0;
            }
        for (int i=0;i<m;i++)
        {
            int a,b,s;
            cin>>a>>b>>s;
            dp[a][b] = s;
        }
        if (solve(n))
        {
            int a,b;
            while (cin>>a>>b&&(a||b))
            {
                if (dp[a][b] < INF)
                    cout<<dp[a][b]<<endl;
                else
                    cout<<"Can`t arrive "<<b<<" from "<<a<<endl;
            }

        }
        else
            cout<<"Have negative loop\n";
    }
    return 0;
}


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