一、内容
湖中有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代表你得到的答案。
每个样例后输出一个空行。
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
二、思路
- 叫求1点到2点的每条路径中最长边中的最小值。
- 直接用floyd求解,max(g[i][k], g[k][j]) 代表表中的最大值,然后再取一个min就是所有最大值中的最小值了。
- 注意输出的时候用.3f
三、代码
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 205;
struct Point {
int x, y;
} p[N];
int n;
double g[N][N];
double getD(int i, int j) {
//返回2点之间的距离
int x = p[i].x - p[j].x, y = p[i].y - p[j].y;
return sqrt(1.0 * x * x + 1.0 * y * y);
}
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]));
}
}
}
}
int main() {
int cnt = 1;
while (scanf("%d", &n), n) {
for (int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) g[i][j] = 1e9;
}
for (int i = 1; i <= n; i++) {
scanf("%d%d", &p[i].x, &p[i].y);
}
//对每2个点进行建边
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
g[i][j] = g[j][i] = min(getD(i, j), g[i][j]);
}
}
//求一次folyd
floyd();
printf("Scenario #%d\nFrog Distance = %.3f\n\n", cnt++, g[1][2]);
}
return 0;
}