BZOJ 2429: [HAOI2006]聪明的猴子
Submit: 1502 Solved: 855
[Submit][Status][Discuss]
Description
在一个热带雨林中生存着一群猴子,它们以树上的果子为生。昨天下了一场大雨,现在雨过天晴,但整个雨林的地
表还是被大水淹没着,部分植物的树冠露在水面上。猴子不会游泳,但跳跃能力比较强,它们仍然可以在露出水面
的不同树冠上来回穿梭,以找到喜欢吃的果实。现在,在这个地区露出水面的有N棵树,假设每棵树本身的直径都
很小,可以忽略不计。我们在这块区域上建立直角坐标系,则每一棵树的位置由其所对应的坐标表示(任意两棵树
的坐标都不相同)。在这个地区住着的猴子有M个,下雨时,它们都躲到了茂密高大的树冠中,没有被大水冲走。由
于各个猴子的年龄不同、身体素质不同,它们跳跃的能力不同。有的猴子跳跃的距离比较远(当然也可以跳到较近
的树上),而有些猴子跳跃的距离就比较近。这些猴子非常聪明,它们通过目测就可以准确地判断出自己能否跳到
对面的树上。【问题】 现已知猴子的数量及每一个猴子的最大跳跃距离,还知道露出水面的每一棵树的坐标,你
的任务是统计有多少个猴子可以在这个地区露出水面的所有树冠上觅食。
Input
第1行为一个整数,表示猴子的个数M(2<=M<=500);
第2行为M个整数,依次表示猴子的最大跳跃距离(每个整数值在1--1000之间);
第3行为一个整数表示树的总棵数N(2<=N<=1000);
第4行至第N+3行为N棵树的坐标(横纵坐标均为整数,范围为:-1000--1000)。
(同一行的整数间用空格分开)
Output
包括一个整数,表示可以在这个地区的所有树冠上觅食的猴子数
Sample Input
4
1 2 3 4
6
0 0
1 0
1 2
-1 -1
-2 0
2 2
1 2 3 4
6
0 0
1 0
1 2
-1 -1
-2 0
2 2
Sample Output
3
HINT
2<=N <= 1000,1<=M=500
Source
kruskal
卡堆优化prim 我屮艸芔茻
#include <algorithm> #include <cstdio> #include <cmath> #define N 1005 using namespace std; int cnt,n,m,dis[N],x[N],y[N],fa[N]; double val[N<<1]; double calc(int x1,int y1,int x2,int y2) {return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));} struct Edge { int x,y;double z; bool operator<(Edge a)const { return z<a.z; } }e[N<<10]; bool vis[N]; int find_(int x){return fa[x]==x?x:fa[x]=find_(fa[x]);} int Main() { scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&dis[i]); scanf("%d",&m); for(int i=1;i<=m;++i) fa[i]=i,scanf("%d%d",&x[i],&y[i]); for(int i=1;i<=m;++i) for(int j=i+1;j<=m;++j) e[++cnt]=(Edge){i,j,calc(x[i],y[i],x[j],y[j])}; sort(e+1,e+1+cnt); double maxn=0.0; int num=0; for(int i=1;i<=cnt;++i) { int fx=find_(e[i].x),fy=find_(e[i].y); if(fx==fy) continue; fa[fy]=fx; num++; if(num==m-1) {maxn=e[i].z;break;} } int sum=0; for(int i=1;i<=n;++i) if(dis[i]*1.0>=maxn) sum++; printf("%d",sum); return 0; } int sb=Main(); int main(int argc,char *argv[]){;}
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。