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
题意:给第一点是青蛙的坐标,第二个是妹子的坐标,其他的点是石头的坐标,现在要问青蛙到妹子的地方,至少需要跳的最大距离,不是最短路问题,路可以很长,跳的石头很多,要求是跳的最大距离能最小。
因为给的都是节点(石头)的坐标,因此先要手动算边权。
要计算最大距离最小,就选择从源点出发,到达所有节点里距离最小的一段进行对其他边的松弛。dist【j】记录到达每个节点的路径中最长的一段的大小,这个值要尽量的小。因此每次更新(松弛)dist[j]时,要取尽量小的值,在更新(松弛)dist[j]的候选值中,拿自己原先到达此节点值,和经过mini走过的路径中的最短值取较小的。
而通过mini走到j点的路径中,我们要找到这段路上的最大值,也就是说,如果从mini到达j的距离比从源点到达mini的某段最长距离还长,那么这个较短的最长距离将被抬高,如果从Mini到达J点的距离不是很长,比从源点到达mini的某段最长距离还短,那么这段经过mini到达j的路径上最长小段距离不变,继承之前dist【mini】的值。
这样不断松弛更新,最后得到 从源点走到1点的路径中,在所有短中的最长距离是最小的一种走法。也就是说走的不一定是最短路,即使绕远,我也是由一段段短距离的边组成的
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
double ma[208][208];
double dist[208];
bool vis[208];
int n,cas=0;
void dijkstra()
{
for(int i=0; i<=200; i++)dist[i]=1e10;
memset(vis,false,sizeof(vis));///利用最短路,使选择的路径都是较小的
for(int i=1; i<n; i++)
dist[i]=ma[0][i];
dist[0]=0;
vis[0]=true;
for(int i=1; i<n; i++)
{
double minn=1e10;
int mini;
for(int j=0; j<n; j++)///每次标记(行走的)路段都是找到到达余下点中最短的
{
if(!vis[j]&&dist[j]<minn)
{
minn=dist[j];
mini=j;
}
}
vis[mini]=true;///找到了最短路段后,更新寻找到达剩余点最短距离
for(int j=0; j<n; j++)///注意,这里dist记录的是到达某个点的最短路径上最长路段的大小,到达每个点后这个最大距离将被记录并继承下去,如果经过了这个点有了一个最大路段
{
///那么这个最大路段值也将成为下一个点的最大路段值,因为到达下一个点经过了当前这条路
dist[j]=min(dist[j],max(dist[mini],ma[mini][j]));///从dist[j]到达自己的最大路中选择比较小的,可以这样想,既然已经到达了dist,那么这段距离就是最小的,其他距离较大的点不会影响从0点到达1点的长度
}///剩下两个候选值,是上一个点的最大距离,以及从上一个点到达自己的最大距离的更新,如果上一个点到达自己的距离更大,那么这个最大距离不从之前继承,而被更新。且这个最大距离特别大时,不会影响提前到达的j点的最小距离,也就是不会绕远路
// for(int i=0;i<n;i++)printf("%d ----->%f\n",i,dist[i]);
// printf("======\n");
}
}
int main()///题目要求,从点0出发,输出到达点1经过的路段中的最大值,从0到1的长度不做要求,但从0到1中所有路段的最大值比未走的路段都小
{
while(scanf("%d",&n)!=EOF)
{
if(!n)return 0;
memset(ma,0,sizeof(ma));
int x[208],y[208];
for(int i=0; i<n; i++) scanf("%d%d",&x[i],&y[i]);
for(int i=n-1; i>=0; i--)
for(int j=i-1; j>=0; j--)
ma[i][j]=ma[j][i]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
dijkstra();
printf("Scenario #%d\n",++cas);
printf("Frog Distance = %.3f\n\n",dist[1]);
}
}