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 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
这道题是最短路的变形,可以利用最短路的原理来求解.
因为数据量只有200,用弗洛伊德也可以。
题意有些难理解,要求出最小的必要跳跃距离,在一条路径(走法)中两块石头的最大距离叫做必要跳跃距离,每种走法都有一个必要跳跃距离,要求出最小的必要跳跃距离。
最短路的原理是在i,j两点间引入一个点k,如果m[i][j]小于m[i][k]+m[k][j],那么就更新m[i][j]间的最短距离为m[i][k]+m[k][j]。
因为只给出了坐标,所以我们需要算出任意两点间的距离,再利用弗洛伊德最短路的形式,对任意两点i,j加入第三点k进行判断,如果引入的两条边(m[i][k]和m[k][j])中的最大值小于m[i][j],则可以引入k点,从而不走i-j这条路,走i-k-j这条路,从而更新m[i][j]更小的必要跳跃距离为max(m[i][k],m[k][j])。
注意第2块石头才是终点 QAQ
弗洛伊德算法
#include<stdio.h>
#include<math.h>
#include<iostream>
using namespace std;
typedef pair<double,double> P;
P p[205];//记录石头的坐标
double m[205][205];//记录两石头间的距离
int main()
{
int n,num=1;
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=1;i<=n;i++)
scanf("%lf%lf",&(p[i].first),&(p[i].second));//石头的坐标
for(int i=1;i<=n;i++)//计算两石头间的距离
for(int j=i+1;j<=n;j++)
m[i][j]=m[j][i]=sqrt((p[i].first-p[j].first)*(p[i].first-p[j].first)+(p[i].second-p[j].second)*(p[i].second-p[j].second));
for(int k=1;k<=n;k++)
for(int i=1;i<=n-1;i++)
for(int j=1;j<=n;j++)
if(m[i][j]>max(m[i][k],m[k][j]))
m[j][i]=m[i][j]=max(m[i][k],m[k][j]);
printf("Scenario #%d\n",num++);
printf("Frog Distance = %.3lf\n\n",m[1][2]);
}
return 0;
}
迪杰斯特拉算法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f, N = 205;
double ma[N][N], x[N], y[N];
double dis[N];
bool vis[N];
int n, m, st, ed;
void init()
{
// 初始化ma数组
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
ma[i][j] = (i == j ? 0 : INF);
}
void Dijk()
{
for (int i = 0; i < n - 1; i++){
double minv = INF;
int k; // k用来存储最小的且没被松弛过的城市
for (int j = 1; j <= n; j++){
if (minv > dis[j] && !vis[j]){
minv = dis[j];
k = j;
}
}
vis[k] = 1;
for (int h = 1; h <= n; h++)
dis[h] = min(dis[h], max(dis[k], ma[k][h]));
}
}
int main(void)
{
int idx = 1;
int a, b, c;
while (cin >> n && n) {
// 初始化ma数组
init();
for (int i = 1; i <= n; i++) {
cin >> x[i] >> y[i];
}
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
ma[i][j] = ma[j][i] = sqrt(fabs(x[i] - x[j]) * fabs(x[i] - x[j]) + fabs(y[i] - y[j]) * fabs(y[i] - y[j]));
}
}
// 输入起点和终点
st = 1, ed = 2;
// 初始化dis数组
for (int i = 1; i <= n; i++)
dis[i] = ma[st][i];
// 初始化vis数组
memset(vis, 0, sizeof vis);
vis[st] = 1;
Dijk();
printf("Scenario #%d\n", idx++);
printf("Frog Distance = %.3lf\n\n", dis[ed]);
}
return 0;
}