Floyd-Warshall算法

Floyd-Warshall算法

算法簡介;

Floyd-Warshall算法(以下簡稱floyd)是求解圖中任意兩點最短路問題的算法。運用的思想是動態規劃。

   狀態轉移方程 dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j])(1<=k<=n)

int n;//節點個數
void init()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			dist[i][j]=INF;//初始賦值爲無窮,這裏是指很大的數,一般爲最大值的1/2 -1
		}
	}
}

void floyd()//注意k,i,j的順序,需細細體會
{
    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(dist[i][j]>dist[i][k]+dist[k][j])
                    dist[i][j]=dist[i][k]+dist[k][j];
            }
        }
    }
}


例題 HDU1596

題目中文,也很好理解。題意就不說了。設兩星球之間的安全值爲safe,則-ln(safe)爲兩點之間的路徑,則就變成了求任意兩點的最短路的問題了

代碼如下:

#include<iostream>
#include<cstdio>
#include<cmath>
#define E 2.718282
using namespace std;
const int inf=1e+9;
const int maxn=1005;
double d[maxn][maxn];
int n;

void floyd()
{
    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(d[i][j]>d[i][k]+d[k][j])
                    d[i][j]=d[i][k]+d[k][j];
            }
        }
    }
}

int main()
{

    while(cin>>n)
    {
        double cost;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                    scanf("%lf",&cost);
                    if(cost==0)
                    {
                        d[i][j]=inf;
                    }
                    else
                        d[i][j]=-log(cost);
            }
        }
        floyd();
        int check;
        scanf("%d",&check);
        int a,b;
        for(int i=0;i<check;i++)
        {
            scanf("%d %d",&a,&b);
            if(d[a][b]!=inf)
                printf("%.3f\n",pow(E,-d[a][b]));
            else
                puts("What a pity!");
        }
    }
    return 0;
}

你也可以不用將安全值轉換成路徑,畢竟調用log,pow函數還是會產生誤差的

代碼如下:

#include<iostream>
#include<cstdio>
#include<cmath>
#define E 2.718282
using namespace std;
const int maxn=1005;
double d[maxn][maxn];
int n;

void floyd()
{
    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(d[i][j]<d[i][k]*d[k][j])
                    d[i][j]=d[i][k]*d[k][j];
            }
        }
    }
}

int main()
{

    while(cin>>n)
    {
        double cost;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                    scanf("%lf",&cost);
                   d[i][j]=cost;
            }
        }
        floyd();
        int check;
        scanf("%d",&check);
        int a,b;
        for(int i=0;i<check;i++)
        {
            scanf("%d %d",&a,&b);
            if(d[a][b]!=0)
                printf("%.3f\n",d[a][b]);
            else
                puts("What a pity!");
        }
    }
    return 0;
}


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