BZOJ1821 [JSOI2010] Group 部落划分 Group

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1821

Description

聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗。只是,这一切都成为谜团了——聪聪根本就不知道部落究竟是如何分布的。 不过好消息是,聪聪得到了一份荒岛的地图。地图上标注了N个野人居住的地点(可以看作是平面上的坐标)。我们知道,同一个部落的野人总是生活在附近。我们把两个部落的距离,定义为部落中距离最近的那两个居住点的距离。聪聪还获得了一个有意义的信息——这些野人总共被分为了K个部落!这真是个好消息。聪聪希望从这些信息里挖掘出所有部落的详细信息。他正在尝试这样一种算法: 对于任意一种部落划分的方法,都能够求出两个部落之间的距离,聪聪希望求出一种部落划分的方法,使靠得最近的两个部落尽可能远离。 例如,下面的左图表示了一个好的划分,而右图则不是。请你编程帮助聪聪解决这个难题。 

Input

第一行包含两个整数N和K(1< = N < = 1000,1< K < = N),分别代表了野人居住点的数量和部落的数量。
接下来N行,每行包含两个正整数x,y,描述了一个居住点的坐标(0 < =x, y < =10000)

Output

输出一行,为最优划分时,最近的两个部落的距离,精确到小数点后两位。

贪心,把边权小的边划分到部落内部,第n - k + 1条边的边权就是答案。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #define rep(i,l,r) for(int i=l; i<=r; i++)
 7 #define clr(x,y) memset(x,y,sizeof(x))
 8 #define travel(x) for(Edge *p=last[x]; p; p=p->pre)
 9 using namespace std;
10 const int INF = 0x3f3f3f3f;
11 const int maxn = 1010;
12 inline int read(){
13     int ans = 0, f = 1;
14     char c = getchar();
15     for(; !isdigit(c); c = getchar())
16     if (c == '-') f = -1;
17     for(; isdigit(c); c = getchar())
18     ans = ans * 10 + c - '0';
19     return ans * f;
20 }
21 struct Edge{
22     int from,to;
23     double cost;
24     inline bool operator < (const Edge &_Tp) const{
25         return cost < _Tp.cost;
26     }
27 }edge[500010];
28 struct Point{
29     int x,y;
30 }t[maxn];
31 int n,k,cnt=0,tot=0,fa[maxn];
32 inline double getdis(Point a,Point b){
33     return sqrt((a.x-b.x) * (a.x-b.x) + (a.y-b.y) * (a.y-b.y));
34 }
35 inline void addedge(int x,int y,double dis){
36     edge[++cnt].from = x; edge[cnt].to = y; edge[cnt].cost = dis;
37 }
38 int getfa(int x){
39     return fa[x] == x ? x : fa[x] = getfa(fa[x]);
40 }
41 int main(){
42     n = read(); k = read();
43     rep(i,1,n) t[i].x = read(), t[i].y = read(), fa[i] = i;
44     rep(i,1,n-1) rep(j,i+1,n) addedge(i,j,getdis(t[i],t[j]));
45     sort(edge+1,edge+cnt+1);
46     k = n - k;
47     rep(i,1,cnt){
48         int a = getfa(edge[i].from), b = getfa(edge[i].to);
49         if (a == b) continue;
50         fa[a] = b;
51         if (++tot > k){
52             printf("%.2lf\n",edge[i].cost);
53             return 0;
54         }
55     }
56     return 0;
57 }
View Code

 

posted on 2016-03-02 18:31  ACMICPC  阅读(283)  评论(0编辑  收藏  举报

导航