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算法的实现。

发布了67 篇原创文章 · 获赞 2 · 访问量 1847

猜你喜欢

转载自blog.csdn.net/weixin_44641254/article/details/104135890