POJ 2253 Frogger(floyd dijkstra spfa)

题目链接:http://poj.org/problem?id=2253

题目:

弗雷迪青蛙正坐在湖中央的一块石头上。 突然,他注意到正坐在另一块石头上的菲奥娜青蛙。 他打算去看望她,但由于水很脏,游客的防晒霜很多,他想避免游泳,而是通过跳跃来到她身边。
不幸的是,菲奥娜的石头超出了他的跳跃范围。 因此,弗雷迪考虑使用其他石头作为中间站点并通过一系列小跳跃到达她。
要执行给定的跳跃序列,青蛙的跳跃范围显然必须至少与序列中发生的最长跳跃一样长。
因此,两块宝石之间的青蛙距离(人类也称之为极小极大距离)被定义为两块宝石之间所有可能路径上的最小必要跳跃范围。

您将获得Freddy石头,Fiona石头和湖中所有其他石头的坐标。 你的工作是计算弗雷迪和菲奥娜之间的青蛙距离(最小必要跳跃距离)。

输入: 

输入将包含一个或多个测试用例。每个测试用例的第一行将包含结石数n(2 <= n <= 200)。接下来的n行每行包含两个整数xi,yi(0 <= xi,yi <= 1000),表示石头#i的坐标。石头#1是弗雷迪的石头,石头#2是菲奥娜的石头,其他的n-2石头是无人居住的。每个测试用例后面都有一个空白行。对于n,输入以零(0)的值终止。

输出:

对于每个测试用例,打印一行“Scenario #x”和一行“Frog Distance = y”,其中x由测试用例编号替换(编号从1开始),y由相应的实数替换,打印到三位小数。在每个测试用例之后放一个空行,即使在最后一个测试用例之后。 

思路:说一下最小必要跳跃距离(也就是他们所说的最长路中的最短路),比如说我们要从1 -> 8,我们有两条路:1 -> 4 -> 6 -> 8 和 1 -> 4 -> 8。这两条路我们要过去,跳的距离就一定要大于等于路中最大两点的距离(不然就到不了8这个点),这个距离就叫必要跳跃距离,第一条路必要跳跃距离是3,第二条是4,题目让我们求的是最小的必要跳跃距离,所以是3。理解这个那这一题就很简单了,三种最短路算法任意一种都可以求解。

还要注意一点:事实上,printf中没有定义%lf,但是很多系统可能会接受它。要确保可移植性,就要坚持使用%f。

建议大家使用double类型时,用%lf输入%f输出避免出错。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
typedef long long LL;
const int N = 1000;
const int INF = 0x3f3f3f3f;

double dis[N], G[N][N];
int n, s;
int Case = 1;
bool vis[N];
struct node{ double x,y;} edge[N];
double dist(node a,node b){
	return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));}

void dijkstra()
{
    for(int i = 1; i <= n; i++)
        dis[i] = G[1][i];
    dis[1] = 0;
    for(int i = 1; i <= n; i++)
    {
        int k = -1;
        for(int j = 1; j <= n; j++)
        {
            if(!vis[j] && (k == -1 || dis[j] < dis[k]))
                k = j;
        }
        if(k == -1) break;
        vis[k] = true;
        for(int j = 1; j <= n; j++)
        {
            if(!vis[j]) dis[j] = min(dis[j], max(dis[k],G[k][j]));
        }
    }
    printf("Scenario #%d\nFrog Distance = %.3f\n\n",Case++,dis[2]);
}

void floyd()
{
    for(int k = 1; k <= n; k++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                G[i][j] = min(G[i][j], max(G[i][k],G[k][j]));
    printf("Scenario #%d\nFrog Distance = %.3f\n\n",Case++,G[1][2]);
}

void spfa()
{
    queue<int>que;
    for(int i = 1; i <= n; i++)
        dis[i] = INF;
    dis[1] = 0;
    vis[1] = true;
    que.push(1);
    while(!que.empty())
    {
        int now = que.front();
        que.pop();
        vis[now] = false;
        for(int i = 1; i <= n; i++)
        {
            if(dis[i] > max(dis[now],G[now][i]))
            {
                dis[i] = max(dis[now],G[now][i]);
                if(!vis[i])
                {
                    vis[i] = true;
                    que.push(i);
                }
            }
        }
    }
    printf("Scenario #%d\nFrog Distance = %.3f\n\n",Case++,dis[2]);
}

int main()
{
    while(~scanf("%d", &n) && n)
    {
        memset(vis, false, sizeof(vis));
        for(int i = 1; i <= n; i++)
            scanf("%lf%lf",&edge[i].x,&edge[i].y);
        for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            G[i][j] = dist(edge[i],edge[j]);
        dijkstra();
        //floyd();
        //spfa();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sugarbliss/article/details/81332266
今日推荐