B - Frogger POJ - 2253

Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to visit her, but since the water is dirty and full of tourists‘ sunscreen, he wants to avoid swimming and instead reach her by jumping.
Unfortunately Fiona‘s stone is out of his jump range. Therefore Freddy considers to use other stones as intermediate stops and reach her by a sequence of several small jumps.
To execute a given sequence of jumps, a frog‘s jump range obviously must be at least as long as the longest jump occuring in the sequence.
The frog distance (humans also call it minimax distance) between two stones therefore is defined as the minimum necessary jump range over all possible paths between the two stones.

You are given the coordinates of Freddy‘s stone, Fiona‘s stone and all other stones in the lake. Your job is to compute the frog distance between Freddy‘s and Fiona‘s stone.

Input

The input will contain one or more test cases. The first line of each test case will contain the number of stones n (2<=n<=200). The next n lines each contain two integers xi,yi (0 <= xi,yi <= 1000) representing the coordinates of stone #i. Stone #1 is Freddy‘s stone, stone #2 is Fiona‘s stone, the other n-2 stones are unoccupied. There‘s a blank line following each test case. Input is terminated by a value of zero (0) for n.

Output

For each test case, print a line saying "Scenario #x" and a line saying "Frog Distance = y" where x is replaced by the test case number (they are numbered from 1) and y is replaced by the appropriate real number, printed to three decimals. Put a blank line after each test case, even after the last one.

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

初看似乎很难把这道题与单源最短路联系在一起。但我们可以做以下分析:

Dijkstra的贪心思想是基于这样一种前提:

设A→P1→P2→P3→B是A到B的最短路,则其中任意一部分亦是最短路。例如P1→P2→P3必然是P1到P3的最短路。证明很简单。假设P1到P3存在一条更短的路,则A到B便可通过该路获得一条更短的路,与题设“A→P1→P2→P3→B是A到B的最短路”矛盾。

由此便得到了Dijkstra的松弛方程:

枚举u。if (d[v]>d[u]+w(u,v)) then d[v]←d[u]+w(u,v)

其中d为源到点最短路长度。u为中转节点。w为u到v的最短路长度。

这是否能和本题的求解过程等同呢?

对于本题,易得两点间最长边最短的路径可能不唯一。但题目只关心点1到点2所有路径中最短的最长边的长度,并不关心具体路径。所以我们在求解过程中,可以人为定义所求路径满足以下条件:

设A→P1→P2→P3→B是我们想要求得的路径,则它满足其中任意一部分亦满足最长边最短。例如P1→P2→P3亦是所有P1到P3路径中最长边最短的。

这样一来,本题的求解,也满足了与Dijkstra相似的贪心过程。它的松弛方程为:

枚举j。if(dis[j]>max(dis[k],map[k][j])) then dis[j]=max(dis[k],map[k][j])

它的意思是,枚举所有中间点k,源到j的目标路径的最长边,要么在源到k这段,要么在k到j这段。

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <queue>
#include <map>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <numeric>
#include <cmath>
#include <iomanip>
#include <deque>
//#include <unordered_set>
//#include <unordered_map>
//#include <xfunctional>
#define ll  long long
#define PII  pair<int, int>
using namespace std;
int dir[5][2] = { { 0,1 } ,{ 0,-1 },{ 1,0 },{ -1,0 } ,{ 0,0 } };
const long long INF = 0x7f7f7f7f7f7f7f7f;
const int inf = 0x3f3f3f3f;
const double pi = 3.14159265358979;
const int mod = 1e9 + 7;
const int maxn = 205;
//if(x<0 || x>=r || y<0 || y>=c)
//1000000000000000000
double x[maxn], y[maxn];
int sizedis = maxn*maxn;
double v[maxn][maxn];
vector<double> dis(sizedis, inf);
double dijkstra(int n)
{
    for (int i = 1; i <= n; i++)
        dis[i] = v[i][1];
    dis[1] = 0;
    vector<bool> vis(maxn, false);
    for (int i = 1; i < n; i++)
    {
        int mini = 0;
        double minn = inf;
        for (int j = 1; j <= n; j++)
        {
            if (!vis[j] && dis[j] < minn)
            {
                mini = j;
                minn = dis[j];
            }
        }
        vis[mini] = true;
        for (int j = 1; j <= n; j++)
        {
            if (!vis[j])
            {
                double mmax = max(minn, v[j][mini]);
                if (mmax < dis[j])
                    dis[j] = mmax;
            }
        }
    }
    return dis[2];
}
int main()
{
    int n,scen=0;
    while (cin >> n && n != 0)
    {
        scen++;
        cout << "Scenario #" << scen << endl;
        for (int i = 1; i <= n; i++)
        {
            cin >> x[i];
            cin >> y[i];
        }
        for (int i = 1; i <= n; i++)
        {
            for (int j = i + 1; j <= n; j++)
                v[i][j] = v[j][i] = sqrt((x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]));
        }
        cout << "Frog Distance = ";
        printf("%.3f\n\n", dijkstra(n));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/dealer/p/12602347.html

时间: 2024-11-04 16:12:29

B - Frogger POJ - 2253的相关文章

Frogger POJ 2253

http://poj.org/problem?id=2253 题意:有一只青蛙A想要跳到另一只青蛙B处, 由于青蛙A的跳跃幅度没有那么大, 所以它需要借助它周边的一些石头从而到达青蛙B处.问你在众多可供选择的道路中,哪条道路中跳跃的最大值要比其他道路中的最大值小.(也就是求它的跳跃幅度至少要为多少) #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #inclu

floyd类型题UVa-10099-The Tourist Guide +Frogger POJ - 2253

The Tourist Guide Mr. G. works as a tourist guide. His current assignment is to take some tourists from one city to another. Some two-way roads connect the cities. For each pair of neighboring cities there is a bus service that runs only between thos

Frogger - poj 2253 (Dijkstra)

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 28802   Accepted: 9353 Description Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to visit her, but sinc

Frogger POJ - 2253(求两个石头之间”所有通路中最长边中“的最小边)

题意 ? 题目主要说的是,有两只青蛙,在两个石头上,他们之间也有一些石头,一只青蛙要想到达另一只青蛙所在地方,必须跳在石头上.题目中给出了两只青蛙的初始位置,以及剩余石头的位置,问一只青蛙到达另一只青蛙所在地的所有路径中的"the frog distance"中的最小值. ? 解释一下"the frog distance": 题目中给出了一段解释"The frog distance (humans also call it minimax distance

POJ 2253 Frogger

题意:一只青蛙找到另外一只青蛙,不过可以通过其它的石头跳到目标青蛙的位置去,其中,输入数据的时候第一组数据是第一只青蛙的位置,第二组是目标青蛙的位置,其它的为石头的位置 思路:dijkstra算法的一种小小的变形,做法还是一样的 Tips:POJ上的双精度浮点型输出竟然是%f输出害的我一直错,或者是编译错误,恼啊! AC代码: #include<cstdio> #include<cmath> #include<algorithm> using namespace std

[2016-04-02][POJ][2253][Frogger]

时间:2016-04-02 17:55:33 星期六 题目编号:[2016-04-02][POJ][2253][Frogger] 题目大意:给定n个点的坐标,问从起点到终点的所有路径中,最大边的最小值是多少,即每一步至少是多少才能走到终点 分析: 方法1: 枚举出完全图,然后从起点跑一次Dijkstra算法,不过选点不再是选择起点到终点路径的点,而是起点到终点的路径中,边最大边最小的点,即d数组保存起点到当前点的路径中最大边的最小值, 最大边的最小值:u->v d[v] = min(d[i],m

Floyd-Warshall算法(求解任意两点间的最短路) 详解 + 变形 之 poj 2253 Frogger

/* 好久没有做有关图论的题了,复习一下. --------------------------------------------------------- 任意两点间的最短路(Floyd-Warshall算法) 动态规划: dp[k][i][j] := 节点i可以通过编号1,2...k的节点到达j节点的最短路径. 使用1,2...k的节点,可以分为以下两种情况来讨论: (1)i到j的最短路正好经过节点k一次 dp[k-1][i][k] + dp[k-1][k][j] (2)i到j的最短路完全

POJ 2253 - Frogger (floyd)

A - Frogger Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to

poj 2253 Frogger 解题报告

题目链接:http://poj.org/problem?id=2253 题目意思:找出从Freddy's stone  到  Fiona's stone  最短路中的最长路. 很拗口是吧,举个例子.对于 i 到 j 的一条路径,如果有一个点k, i 到 k 的距离 && k 到 j 的距离都小于 i 到 j 的距离,那么就用这两条中较大的一条来更新 i 到 j 的距离 .每两点之间都这样求出路径.最后输出 1 到 2 的距离(1:Freddy's stone   2:Fiona's sto