题目要求最近的两个部落间距尽可能最远
不难想到一种贪心的方法,对每两个点之间距离从小到大排序,
把每个点看成一个部落
然后不断将距离近的两个部落合并成一个部落,直到剩下了k个部落,那么下一条不同部落之间的边的长度就是答案
显然这个算法是用并查集实现
type node=record
x,y:longint;
w:double;
end; var a:array[..] of node;
fa,d,x,y:array[..] of longint;
k,i,j,k1,k2,m,n:longint; function getf(x:longint):longint;
begin
while fa[x]<>x do x:=fa[x];
exit(x);
end; procedure swap(var a,b:node);
var c:node;
begin
c:=a;
a:=b;
b:=c;
end; procedure sort(l,r:longint);
var i,j:longint;
x:double; begin
i:=l;
j:=r;
x:=a[(l+r) shr ].w;
repeat
while a[i].w<x do inc(i);
while x<a[j].w do dec(j);
if not(i>j) then
begin
swap(a[i],a[j]);
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; begin
readln(n,k);
for i:= to n do
readln(x[i],y[i]);
for i:= to n- do
for j:=i+ to n do
begin
inc(m);
a[m].x:=i;
a[m].y:=j;
a[m].w:=sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]));
end;
sort(,m);
for i:= to n do
begin
fa[i]:=i;
d[i]:=;
end;
j:=n;
for i:= to m do
begin
k1:=getf(a[i].x);
k2:=getf(a[i].y);
if k1<>k2 then
begin
if d[k1]>d[k2] then fa[k2]:=k1
else begin
fa[k1]:=k2;
if d[k1]=d[k2] then inc(d[k2]);
end;
dec(j);
end;
if j=k- then //剩下k个部落后,下一条【不同】部落之间的边才是答案
begin
writeln(a[i].w::);
break;
end;
end;
end.