1821: [JSOI2010]Group 部落划分 Group
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1308 Solved: 627[][]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
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 var11 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 begin18 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 begin24 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 begin30 exit(getfat(x)=getfat(y));31 end;32 procedure swap(var x,y:longint);inline;33 var z:longint;34 begin35 z:=x;x:=y;y:=z;36 end;37 procedure sort(l,r:longint);38 var i,j:longint;x,y:extended;39 begin40 i:=l;j:=r;x:=b[(l+r) div 2];41 repeat42 while b[i]x do dec(j);44 if i<=j then45 begin46 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 m do76 begin77 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.