Frogger POJ - 2253(最短路)

湖中有n塊石頭,編號從1到n,有兩隻青蛙,Bob在1號石頭上,Alice在2號石頭上,Bob想去看望Alice,但由於水很髒,他想避免游泳,於是跳着去找她。但是Alice的石頭超出了他的跳躍範圍。因此,Bob使用其他石頭作爲中間站,通過一系列的小跳躍到達她。兩塊石頭之間的青蛙距離被定義爲兩塊石頭之間所有可能路徑上的最小必要跳躍距離,某條路徑的必要跳躍距離即這條路徑中單次跳躍的最遠跳躍距離。你的工作是計算Alice和Bob石頭之間的青蛙距離。
Input
多實例輸入
先輸入一個整數n表示石頭數量,當n等於0時結束。
接下來n行依次給出編號爲1到n的石頭的座標xi , yi。
2 <= n <= 200
0 <= xi , yi <= 1000
Output
先輸出"Scenario #x", x代表樣例序號。
接下來一行輸出"Frog Distance = y", y代表你得到的答案。
每個樣例後輸出一個空行。
(ps:wa有可能是精度問題,g++不對可以用c++嘗試,都不對就是代碼問題)
Sample Input
2
0 0
3 4

3
17 4
19 4
18 5

0
Sample Output
Scenario #1
Frog Distance = 5.000

Scenario #2
Frog Distance = 1.414

題意思路:複製一下別人的題意,有兩隻青蛙和若干塊石頭,現在已知這些東西的座標,兩隻青蛙A座標和青蛙B座標是第一個和第二個座標,現在A青蛙想要到B青蛙那裏去,並且A青蛙可以藉助任意石頭的跳躍,而從A到B有若干通路,問從A到B的所有通路上的最大邊,比如有 有兩條通路 1(4)5 (3)2 代表1到5之間的邊爲4, 5到2之間的邊爲3,那麼該條通路跳躍範圍(兩塊石頭之間的最大距離)爲 4, 另一條通路 1(6) 4(1) 2 ,該條通路的跳躍範圍爲6, 兩條通路的跳躍範圍分別是 4 ,6,我們要求的就是最小的那一個跳躍範圍,即4,用三種方法都能解決
代碼:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define maxn 300
#define inf 0x3f3f3f3f
int n,x[maxn],y[maxn];
double mp[maxn][maxn];
void floyd()
{
    for(int k=1; k<=n; k++)
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                mp[i][j]=min(mp[i][j],max(mp[i][k],mp[k][j]));//許多通路中最長邊中的最小邊
}
int main()
{
    int flag=1;
    while(~scanf("%d",&n)&&n!=0)
    {
        memset(mp,0,sizeof(mp));
        for(int i=1; i<=n; i++)
            scanf("%d%d",&x[i],&y[i]);
        for(int i=1; i<=n; i++)
            for(int j=i+1; j<=n; j++)
                mp[i][j]=mp[j][i]=sqrt(double(x[i]-x[j])*(x[i]-x[j])+double(y[i]-y[j])*(y[i]-y[j]));
        floyd();
        printf("Scenario #%d\nFrog Distance = %.3lf\n\n",flag++,mp[1][2]);
    }
    return 0;
}

感悟:floyd算法需要三重循環:第一重枚舉中轉點,k=1-n,第二重就是起點i,也是從1-n,第三重終點j也是一樣的,這裏的k循環一定要在最外層,如果不在最外層,就有可能將k號點可以鬆弛的邊漏掉,影響結果。在循環最裏面判斷dis[i][k]+dis[k][j]是否比dis[i][j]來的優,是的話則更新,這就是Floyed算法的實現。

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