BZOJ1821: [JSOI2010]Group 部落划分
这题乍看很吓人,其实就是一个贪心。
每次取最近的两个点所在的块合并,直到只剩下k块,输出答案。
1 /************************************************************** 2 Problem: 1821 3 User: zhuohan123 4 Language: C++ 5 Result: Accepted 6 Time:136 ms 7 Memory:18492 kb 8 ****************************************************************/ 9 10 #include <iostream> 11 #include <cstdio> 12 #include <cmath> 13 #include <algorithm> 14 using namespace std; 15 int f[1100]; 16 int gf(int p){return p==f[p]?p:f[p]=gf(f[p]);} 17 struct point{double x,y;}p[1100]; 18 double dis(point a,point b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);} 19 struct edge 20 { 21 int from,to;double c; 22 friend bool operator<(edge a,edge b){return a.c<b.c;} 23 }g[1100000];int gnum; 24 int main(int argc, char *argv[]) 25 { 26 int n,k;scanf("%d%d",&n,&k); 27 for(int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y); 28 for(int i=1;i<=n;i++)f[i]=i; 29 for(int i=1;i<=n;i++) 30 for(int j=1;j<i;j++) 31 { 32 g[++gnum].from=i; 33 g[gnum].to=j; 34 g[gnum].c=dis(p[i],p[j]); 35 } 36 sort(g+1,g+gnum+1); 37 for(int i=1;i<=gnum;i++) 38 if(gf(g[i].from)!=gf(g[i].to)) 39 { 40 if(n>k){f[gf(g[i].from)]=gf(g[i].to);n--;} 41 else {printf("%0.2lf\n",sqrt(g[i].c));return 0;} 42 } 43 printf("0.00\n"); 44 return 0; 45 }