Description
国防部计划用无线网络连接若干个边防哨所。2种不同的通讯技术用来搭建无线网络:每个边防哨所都要配备无线电收发器;有一些哨所还可以增配卫星电话。
任意两个配备了一条卫星电话线路的哨所均可以通话,无论它们相距多远。而只通过无线电收发器通话的哨所之间的距离不能超过D,这是受收发器的功率限制。收发器的功率越高,通话距离D会更远,但同时价格也更贵。
收发器需要统一购买和安装,所以全部哨所只能选择安装一种型号的收发器。换句话说,每一对哨所之间的通话距离都是同一个D。
你的任务是确定收发器必须的最小通话距离D,使得每一对哨所之间至少有一条通话路径(直接的或者间接的)。
Input
第1行:2个整数S(1 <= S <= 100)和P(S < P <= 500),S表示可安装的卫星电话的线路数,P表示边防哨所的数量。
接下来P行,每行描述一个哨所的平面坐标(x,y),以km为单位,整数,0<=x,y<=10,000
Output
第1行:1个实数D,表示无线电收发器的最小传输距离。精确到小数点后2位。
Sample Input
2 4
0 100
0 300
0 600
150 750
Sample Output
212.13
分析:最小生成树,用并查集做。因为有卫星电话,所以当我们插入p-s条边时,就可以不用再继续搜了。
代码:
var
a:array [1..500*500] of real;
x,y:array [1..500*500] of longint;
dx,dy,p:Array [1..500] of longint;
i,j,n,s,num,t,sum:longint;
ans:real;
procedure qsort(l,r:longint);
var
i,j,t:longint;
mid,temp:real;
begin
if l>=r then exit;
i:=l; j:=r;
mid:=a[(i+j) div 2];
repeat
while a[i]<mid do inc(i);
while a[j]>mid do dec(j);
if i<=j then
begin
temp:=a[i]; a[i]:=a[j]; a[j]:=temp;
t:=x[i]; x[i]:=x[j]; x[j]:=t;
t:=y[i]; y[i]:=y[j]; y[j]:=t;
inc(i);
dec(j);
end;
until i>j;
qsort(i,r);
qsort(l,j);
end;
function find(x:longint):longint;
var y,root,w:longint;
begin
y:=x;
while p[y]>0 do
y:=p[y];
root:=y;
y:=x;
while p[y]>0 do
begin
w:=p[y];
p[y]:=root;
y:=w;
end;
find:=root;
end;
procedure union(x,y:longint);
var
u,v:longint;
begin
u:=find(x);
v:=find(y);
if u=v then exit;
p[u]:=v;
end;
begin
read(s,n);
for i:=1 to n do
begin
readln(dx[i],dy[i]);
for j:=1 to i-1 do
begin
inc(num);
a[num]:=sqrt(sqr(dx[i]-dx[j])+sqr(dy[i]-dy[j]));
x[num]:=j;
y[num]:=i;
end;
end;
qsort(1,num);
for i:=1 to num do
begin
if find(x[i])<>find(y[i]) then
begin
inc(sum);
ans:=a[i];
union(x[i],y[i]);
end;
if sum=n-s then break;
end;
writeln(ans:0:2);
end.