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 }

 

你可能感兴趣的:(group)