您的位置:首页 > 其它

BZOJ2429 [HAOI2006] 聪明的猴子

2016-01-18 13:30 387 查看
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2429

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

包括一个整数,表示可以在这个地区的所有树冠上觅食的猴子数

下课时水一水放松身心……其实这个Kruskal是乱写的,应该加到n-1条边就break,然而也能AC就懒得改了。

一直写水题这人要完……

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define rep(i,l,r) for(int i=l; i<=r; i++)
#define clr(x,y) memset(x,y,sizeof(x))
#define travel(x) for(Edge *p=last[x]; p; p=p->pre)
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1010;
inline int read(){
int ans = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar())
if (c == '-') f = -1;
for(; isdigit(c); c = getchar())
ans = ans * 10 + c - '0';
return ans * f;
}
struct Edge{
int from,to;
double cost;
inline bool operator < (const Edge &_Tp) const{
return cost < _Tp.cost;
}
}edge[500010];
struct Point{
int x,y;
}t[maxn];
int n,m,cnt=0,h[maxn],fa[maxn];
inline double getdis(Point a,Point b){
return sqrt((a.x-b.x) * (a.x-b.x) + (a.y-b.y) * (a.y-b.y));
}
inline void addedge(int x,int y,double dis){
edge[++cnt].from = x; edge[cnt].to = y; edge[cnt].cost = dis;
}
int getfa(int x){
return fa[x] == x ? x : fa[x] = getfa(fa[x]);
}
int main(){
m = read();
rep(i,1,m) h[i] = read();
n = read();
rep(i,1,n) t[i].x = read(), t[i].y = read();
rep(i,1,n-1) rep(j,i+1,n) addedge(i,j,getdis(t[i],t[j]));
sort(edge+1,edge+cnt+1);
rep(i,1,n) fa[i] = i;
double mx = -INF;
rep(i,1,cnt){
int a = getfa(edge[i].from);
int b = getfa(edge[i].to);
if (a != b){
fa[a] = b;
mx = max(mx,edge[i].cost);
}
}
int ans = 0; rep(i,1,m) if (h[i] >= mx) ans++;
printf("%d\n",ans);
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: