1821: [JSOI2010]Group 部落划分 Group
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1308 Solved: 627
[Submit][Status]
Description
聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗。只是,这一切都成为谜团了——聪聪根本就不知道部落究竟是如何分布的。 不过好消息是,聪聪得到了一份荒岛的地图。地图上标注了N个野人居住的地点(可以看作是平面上的坐标)。我们知道,同一个部落的野人总是生活在附近。我们把两个部落的距离,定义为部落中距离最近的那两个居住点的距离。聪聪还获得了一个有意义的信息——这些野人总共被分为了K个部落!这真是个好消息。聪聪希望从这些信息里挖掘出所有部落的详细信息。他正在尝试这样一种算法: 对于任意一种部落划分的方法,都能够求出两个部落之间的距离,聪聪希望求出一种部落划分的方法,使靠得最近的两个部落尽可能远离。 例如,下面的左图表示了一个好的划分,而右图则不是。请你编程帮助聪聪解决这个难题。
Input
第一行包含两个整数N和K(1<=N<=1000,1<k<=n),分别代表了野人居住点的数量和部落的数量。 接下来n行,每行包含两个正整数x,y,描述了一个居住点的坐标(0<="x," y<="10000)。" <="" div="">
Output
输出一行,为最优划分时,最近的两个部落的距离,精确到小数点后两位。
Sample Input
4 2
0 0
0 1
1 1
1 0
0 0
0 1
1 1
1 0
Sample Output
1.00
HINT
Source
题解:萌萌哒最小生成树不解释(呵呵呵JSOI居然也出现过这样的题目)
1 /************************************************************** 2 Problem: 1821 3 User: HansBug 4 Language: Pascal 5 Result: Accepted 6 Time:272 ms 7 Memory:25656 kb 8 ****************************************************************/ 9 10 var 11 i,j,k,l,m,n,tt:longint; 12 a,d:array[0..1000050,1..2] of longint; 13 14 b:array[0..1000050] of extended; 15 c:array[0..10050] of longint; 16 function getfat(x:longint):longint;inline; 17 begin 18 if c[x]<>x then c[x]:=getfat(c[x]); 19 getfat:=c[x]; 20 end; 21 procedure merge(x,y:longint);inline; 22 var a1,a2:longint; 23 begin 24 a1:=getfat(x);a2:=getfat(y); 25 if a1=a2 then exit; 26 dec(tt);c[a1]:=a2; 27 end; 28 function tog(x,y:longint):boolean;inline; 29 begin 30 exit(getfat(x)=getfat(y)); 31 end; 32 procedure swap(var x,y:longint);inline; 33 var z:longint; 34 begin 35 z:=x;x:=y;y:=z; 36 end; 37 procedure sort(l,r:longint); 38 var i,j:longint;x,y:extended; 39 begin 40 i:=l;j:=r;x:=b[(l+r) div 2]; 41 repeat 42 while b[i]<x do inc(i); 43 while b[j]>x do dec(j); 44 if i<=j then 45 begin 46 y:=b[i]; 47 b[i]:=b[j]; 48 b[j]:=y; 49 swap(a[i,1],a[j,1]); 50 swap(a[i,2],a[j,2]); 51 inc(i);dec(j); 52 end; 53 until i>j; 54 if i<r then sort(i,r); 55 if l<j then sort(l,j); 56 end; 57 58 begin 59 readln(n,m); 60 for i:=1 to n do 61 readln(d[i,1],d[i,2]); 62 k:=0; 63 for i:=1 to n-1 do 64 for j:=i+1 to n do 65 begin 66 inc(k); 67 a[k,1]:=i; 68 a[k,2]:=j; 69 b[k]:=sqrt(sqr(d[i,1]-d[j,1])+sqr(d[i,2]-d[j,2])); 70 end; 71 tt:=n; 72 for i:=1 to n do c[i]:=i; 73 sort(1,k); 74 i:=0; 75 while tt>m do 76 begin 77 inc(i); 78 while tog(a[i,1],a[i,2]) do inc(i); 79 merge(a[i,1],a[i,2]); 80 end; 81 inc(i); 82 while tog(a[i,1],a[i,2]) do inc(i); 83 writeln(b[i]:0:2); 84 end.