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
",sqrt(g[i].c));return 0;}
42         }
43     printf("0.00
");
44     return 0;
45 }
原文地址:https://www.cnblogs.com/zhuohan123/p/3237290.html