Frogger:Floyd,Dijkstra算法的拓展

问题描述:
湖中有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++尝试,都不对就是代码问题)
题意:
复制一下别人的题意,有两只青蛙和若干块石头,现在已知这些东西的坐标,两只青蛙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,用三种方法都能解决
1.Floyd:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#define mem(a,b) memset(a,b,sizeof(a))
#define maxnum 300
#define inf 0x3f3f3f3f
using namespace std;
int x[maxnum],y[maxnum],n;
double map[maxnum][maxnum];
void floyd()
{
    for(int k=1; k<=n; k++)
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                map[i][j]=min(map[i][j],max(map[i][k],map[k][j]));
			//许多通路中最长边中的最小边,这和求最短路不一样,最短路是把i到j,直达或中转最小的一个赋给i到j的直达
			//这个呢,是没有直达(直达就是这条路的最大)就找中转中最大的然后记录,就是Floyd的变形 
}
int main()
{
    int q=1;
    while(~scanf("%d",&n)&&n)
    {
        mem(map,0);
        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++)
                map[i][j]=map[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",q++,map[1][2]);
    }
    return 0;
}

2.Dijkstra

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define maxnum 300
#define inf 0x3f3f3f3f
using namespace std;
int x[maxnum],y[maxnum],n;
double map[maxnum][maxnum];
double dis[maxnum];
int vis[maxnum];
void dj(int s)
{
    mem(vis,0);
    for(int i=1; i<=n; i++)
        dis[i]=inf;
    dis[s]=0;
    for(int i=1; i<=n; i++)
    {
        int minn=inf,k;
        for(int j=1; j<=n; j++)
            if(vis[j]==0&&dis[j]<minn)
            {
                k=j;
                minn=dis[j];
            }
        vis[k]=1;
        for(int j=1; j<=n; j++)
            dis[j]=min(dis[j],max(dis[k],map[k][j]));//dis[j]为从一号石头到第j号石头所有通路中最长边中的最小边,dis[j]是直达,dis[k]前一段,map[k][j]后一段
    }
}
int main()
{
    int q=1;
    while(~scanf("%d",&n)&&n)
    {
        mem(map,0);
        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++)
                map[i][j]=map[j][i]=sqrt(double(x[i]-x[j])*(x[i]-x[j])+double(y[i]-y[j])*(y[i]-y[j]));
        dj(1);
        printf("Scenario #%d\nFrog Distance = %.3lf\n\n",q++,dis[2]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_46687179/article/details/105916271