有一只叫做Freddy的青蛙坐在湖中央的一块石头上,突然间他发现另一只青蛙(她的名字是Fiona)坐在另一颗石头上。他想要过去找她,但是因为湖水很脏,到处充满着游客的防晒油,所以他决定用跳的,而不要用游的。
不妙的是Fiona的石头离他的距离超出他所能跳的范围。因此Freddy考虑利用其它的一些石头当作中继站,因此他就可以跳比较小的距离(或许要跳许多次)去找Fiona。
要这样子连续的跳,很明显的Freddy一次能跳的距离必须至少和这一串石头间的距离最大的距离一样。因此,介于石头间的蛙跳距离(frog distance,人类也称之为minmax distance)定义为要从Freddy所在的石头要跳到Fiona所在的石头的路径中,最小必须要跳的距离。
不妙的是Fiona的石头离他的距离超出他所能跳的范围。因此Freddy考虑利用其它的一些石头当作中继站,因此他就可以跳比较小的距离(或许要跳许多次)去找Fiona。
要这样子连续的跳,很明显的Freddy一次能跳的距离必须至少和这一串石头间的距离最大的距离一样。因此,介于石头间的蛙跳距离(frog distance,人类也称之为minmax distance)定义为要从Freddy所在的石头要跳到Fiona所在的石头的路径中,最小必须要跳的距离。
给你Freddy所在的石头、Fiona所在的石头,以及湖中所有其它石头的坐标,你的任务是算出介于Freddy和Fiona所在石头间的蛙跳距离。
此题要求的边是两点间路径的最大边的最小值。将每两个点连边,按边的长度从小到大排序,然后枚举每条边,不断将边的端点所在的连通块合并,知道某一条边使得起点和终点在一个连通块内了,那么这条边的长度便是答案,因为已经不可能存在比他更小的边可以联通起点和终点了。
CODE:
var
st,ed:array[0..40000] of longint;
dist:array[0..40000] of real;
fa,x,y:array[0..200] of longint;
n,i,j,k,tot,zzb:longint;
function find(x:longint):longint;
begin
if fa[x]=x then exit(x);
fa[x]:=find(fa[x]);
exit(fa[x]);
end;
procedure qsort(l,r:longint);
var i,j,tt:longint;
m,t:real;
begin
i:=l; j:=r; m:=dist[(i+j) div 2];
repeat
while dist[i]<m do inc(i);
while dist[j]>m do dec(j);
if i<=j then
begin
t:=dist[i]; dist[i]:=dist[j]; dist[j]:=t;
tt:=st[i]; st[i]:=st[j]; st[j]:=tt;
tt:=ed[i]; ed[i]:=ed[j]; ed[j]:=tt;
inc(i); dec(j);
end;
until i>j;
if (l<j) then qsort(l,j);
if (i<r) then qsort(i,r);
end;
procedure init;
var i,j,a,b:longint;
begin
readln(n); zzb:=0;
while n<>0 do
begin
inc(zzb);
tot:=0;
for i:=1 to n do
readln(x[i],y[i]);
for i:=1 to n-1 do
for j:=i+1 to n do
begin
inc(tot);
st[tot]:=i;
ed[tot]:=j;
dist[tot]:=sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]));
end;
qsort(1,tot);
for i:=1 to n do
fa[i]:=i;
for i:=1 to tot do
begin
a:=find(st[i]);
b:=find(ed[i]);
if a<>b then
fa[a]:=b;
if find(1)=find(2) then
begin
writeln('Scenario #',zzb);
writeln('Frog Distance = ',dist[i]:0:3);
writeln;
break;
end;
end;
readln(n);
end;
end;
begin
init;
end.