题目要求最近的两个部落间距尽可能最远
不难想到一种贪心的方法,对每两个点之间距离从小到大排序,
把每个点看成一个部落
然后不断将距离近的两个部落合并成一个部落,直到剩下了k个部落,那么下一条不同部落之间的边的长度就是答案
显然这个算法是用并查集实现
1 type node=record 2 x,y:longint; 3 w:double; 4 end; 5 6 var a:array[0..500010] of node; 7 fa,d,x,y:array[0..2010] of longint; 8 k,i,j,k1,k2,m,n:longint; 9 10 function getf(x:longint):longint; 11 begin 12 while fa[x]<>x do x:=fa[x]; 13 exit(x); 14 end; 15 16 procedure swap(var a,b:node); 17 var c:node; 18 begin 19 c:=a; 20 a:=b; 21 b:=c; 22 end; 23 24 procedure sort(l,r:longint); 25 var i,j:longint; 26 x:double; 27 28 begin 29 i:=l; 30 j:=r; 31 x:=a[(l+r) shr 1].w; 32 repeat 33 while a[i].w<x do inc(i); 34 while x<a[j].w do dec(j); 35 if not(i>j) then 36 begin 37 swap(a[i],a[j]); 38 inc(i); 39 j:=j-1; 40 end; 41 until i>j; 42 if l<j then sort(l,j); 43 if i<r then sort(i,r); 44 end; 45 46 begin 47 readln(n,k); 48 for i:=1 to n do 49 readln(x[i],y[i]); 50 for i:=1 to n-1 do 51 for j:=i+1 to n do 52 begin 53 inc(m); 54 a[m].x:=i; 55 a[m].y:=j; 56 a[m].w:=sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j])); 57 end; 58 sort(1,m); 59 for i:=1 to n do 60 begin 61 fa[i]:=i; 62 d[i]:=1; 63 end; 64 j:=n; 65 for i:=1 to m do 66 begin 67 k1:=getf(a[i].x); 68 k2:=getf(a[i].y); 69 if k1<>k2 then 70 begin 71 if d[k1]>d[k2] then fa[k2]:=k1 72 else begin 73 fa[k1]:=k2; 74 if d[k1]=d[k2] then inc(d[k2]); 75 end; 76 dec(j); 77 end; 78 if j=k-1 then //剩下k个部落后,下一条【不同】部落之间的边才是答案 79 begin 80 writeln(a[i].w:0:2); 81 break; 82 end; 83 end; 84 end.