BZOJ 1821 JSOI2010 部落划分 Group prim

Description

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

Input

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

Output

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

Sample Input

4 2
0 0
0 1
1 1
1 0


Sample Output

1.00

题解  

    最小生成树求第K大边

代码

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <ctime>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <set>
 8 #include <vector>
 9 #include <queue>
10 #include <typeinfo>
11 #include <map>
12 #include <stack>
13 typedef long long ll;
14 #define inf 0x7fffffff
15 using namespace std;
16 inline ll read()
17 {
18     ll x=0,f=1;
19     char ch=getchar();
20     while(ch<'0'||ch>'9')
21     {
22         if(ch=='-')f=-1;
23         ch=getchar();
24     }
25     while(ch>='0'&&ch<='9')
26     {
27         x=x*10+ch-'0';
28         ch=getchar();
29     }
30     return x*f;
31 }
32 
33 //**************************************************************************************
34 double mp[1111][1111];
35 double lowcost[1111];
36 int used[1111];
37 int n;
38  int k;
39 int kk;
40 double  ans[1111];
41 void prim()
42 {
43    int x=1;
44    double mn;
45    memset(used,0,sizeof(used));
46    memset(lowcost,0,sizeof(lowcost));
47    for(int i=1;i<=n;i++)
48     lowcost[i]=mp[x][i];
49    used[x]=1;
50    for(int i=2;i<=n;i++)
51    {
52        mn=inf*1.0;
53        for(int j=1;j<=n;j++)
54        {
55            if(!used[j]&&lowcost[j]<mn)
56            {
57                x=j;
58                mn=lowcost[j];
59            }
60        }
61        ans[++kk]=mn;
62        used[x]=1;
63        for(int j=1;j<=n;j++)
64        {
65            if(!used[j]&&mp[x][j]<lowcost[j])
66             lowcost[j]=mp[x][j];
67        }
68    }
69 }
70 int main()
71 {
72  double x[1111];
73  double y[1111];
74     scanf("%d%d",&n,&k);
75     for(int i=1;i<=n;i++)
76     {
77         scanf("%lf%lf",&x[i],&y[i]);
78 
79     }
80     for(int i=1;i<=n;i++)
81     {
82         for(int j=1;j<=n;j++)
83         {
84             if(i==j)mp[i][j]=0;
85             else
86             {
87                 mp[i][j]=sqrt((y[i]-y[j])*(y[i]-y[j])+(x[i]-x[j])*(x[i]-x[j]));
88             }
89         }
90     }
91     kk=0;
92     prim();
93     sort(ans+1,ans+1+kk);
94     printf("%.2f\n",ans[kk-k+2]);
95     return 0;
96 }

 




posted @ 2015-08-03 10:44  meekyan  阅读(174)  评论(0编辑  收藏  举报