P2504 聪明的猴子
题目描述
在一个热带雨林中生存着一群猴子,它们以树上的果子为生。昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着,部分植物的树冠露在水面上。猴子不会游泳,但跳跃能力比较强,它们仍然可以在露出水面的不同树冠上来回穿梭,以找到喜欢吃的果实。
现在,在这个地区露出水面的有N棵树,假设每棵树本身的直径都很小,可以忽略不计。我们在这块区域上建立直角坐标系,则每一棵树的位置由其所对应的坐标表示(任意两棵树的坐标都不相同)。
在这个地区住着的猴子有M个,下雨时,它们都躲到了茂密高大的树冠中,没有被大水冲走。由于各个猴子的年龄不同、身体素质不同,它们跳跃的能力不同。有的猴子跳跃的距离比较远(当然也可以跳到较近的树上),而有些猴子跳跃的距离就比较近。这些猴子非常聪明,它们通过目测就可以准确地判断出自己能否跳到对面的树上。
【问题】现已知猴子的数量及每一个猴子的最大跳跃距离,还知道露出水面的每一棵树的坐标,你的任务是统计有多少个猴子可以在这个地区露出水面的所有树冠上觅食。
输入格式
输入文件monkey.in包括:
第1行为一个整数,表示猴子的个数M(2<=M<=500);
第2行为M个整数,依次表示猴子的最大跳跃距离(每个整数值在1--1000之间);
第3行为一个整数表示树的总棵数N(2<=N<=1000);
第4行至第N+3行为N棵树的坐标(横纵坐标均为整数,范围为:-1000--1000)。
(同一行的整数间用空格分开)
输出格式
输出文件monkey.out包括一个整数,表示可以在这个地区的所有树冠上觅食的猴子数。

数据范围
2≤N≤1000,1≤M≤500
思路:
这道题是一道使用最小生成树的克鲁斯卡尔算法的题。我们要用最小生成树来将所有节点连接起来,并求出将它连接所需的最小距离。
在这道题中,我们将所有的树冠的位置上设置为端点。在读入的时候,我们设一个结构体来分别存储每个端点的横坐标和纵坐标。记录下每一个端点后,我们可以O(n²)枚举每两个端点,求出这些端点中任意两个点之间的距离(因为所有端点间都可以连接,所以我们可以直接构造一个完全图),并且再开一个结构体来存储每一条边的起点、终点和距离。接下来,我们要对边权从小到大进行排序。
我们维护一个对每个端点的并查集,从边权从小到大加入边,直到边数足够即可退出循环。在建最小生成树的时候,我们要不断更新最小生成树中的最长边的长度。因为我们已经对边权进行了从小到大的排序,所以后加入的边边权一定比前加入的边边权大,故在更新最值时不用比较。
最后求出最值后,我们再对猴子的最大跳跃距离从大到小进行排序,然后进行O(n)的从前往后枚举,如果枚举到一只猴子最大距离小于最大边权,则退出枚举,同时输出当前猴子的序号减1的值(从当前猴子开始无法全跳过)。或者如果已经枚举到了最后一只猴子,则只需要输出这只猴子序号即可,因为所有猴子都能到达所有树冠。
这里不需要判断能否建成最小生成树,因为我们建图时建立的是完全图,保证每两点间都能联通。
另外,在求和判断距离时我们不必求出实际距离,而是求出实际距离的平方,同时在读入猴子最大跳跃距离时对其取平方,这样可以避免精度问题和类型转换。
最后是完整代码:
1 #include<iostream>
2 #include<algorithm>
3 using namespace std;
4 int m;
5 int dis[505];
6 int n;
7 struct tree{
8 int x,y;
9 }a[1005];
10 int fa[1005];
11 struct street{
12 int start;
13 int end;
14 int val;
15 }b[1000005];
16 bool cmp(street a,street b){
17 return a.val<b.val;
18 }
19 bool cmp2(int a,int b){
20 return a>b;
21 }
22 int find(int x){
23 if(x==fa[x]){
24 return x;
25 }else{
26 return fa[x]=find(fa[x]);
27 }
28 }
29 void unionn(int x,int y){
30 int r1=find(x);
31 int r2=find(y);
32 fa[r1]=r2;
33 }
34 int main(){
35 cin>>m;
36 for(int i=1;i<=m;i++){
37 cin>>dis[i];
38 }
39 sort(dis+1,dis+m+1,cmp2);//从大到小排序
40 cin>>n;
41 for(int i=1;i<=n;i++){
42 cin>>a[i].x>>a[i].y;
43 }
44 int cnt=1;
45 for(int i=1;i<=n;i++){
46 for(int j=i+1;j<=n;j++){
47 b[cnt].start=i;
48 b[cnt].end=j;
49 b[cnt].val=(a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y);
50 cnt++;
51 }
52 }
53 cnt--;
54 sort(b+1,b+cnt+1,cmp);
55 for(int i=1;i<=n;i++){
56 fa[i]=i;
57 }
58 int sum=0;
59 int ans=-9999;//加入最小生成树的边的边权最大值
60 for(int i=1;i<=cnt;i++){
61 if(find(b[i].start)!=find(b[i].end)){
62 sum++;
63 ans=max(ans,b[i].val);
64 unionn(b[i].start,b[i].end);
65 }
66 if(sum==n-1){
67 break;
68 }
69 }
70 for(int i=1;i<=m;i++){
71 if(dis[i]*dis[i]<ans){
72 cout<<i-1<<endl;
73 break;
74 }
75 if(i==m){
76 cout<<m<<endl;
77 break;
78 }
79 }
80 return 0;
81 }
P2504 聪明的猴子的更多相关文章
- 洛谷—— P2504 [HAOI2006]聪明的猴子
P2504 [HAOI2006]聪明的猴子 题目描述 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着,部分植物的树冠露在水面上. ...
- 洛谷——P2504 [HAOI2006]聪明的猴子
P2504 [HAOI2006]聪明的猴子 题目描述 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着,部分植物的树冠露在水面上. ...
- 洛谷 P2504 [HAOI2006]聪明的猴子
洛谷 P2504 [HAOI2006]聪明的猴子 题目描述 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着,部分植物的树冠露在水 ...
- BZOJ2429[HAOI2006]聪明的猴子[最小生成树 kruskal]
2429: [HAOI2006]聪明的猴子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 896 Solved: 575[Submit][Statu ...
- 最小生成树 2429: [HAOI2006]聪明的猴子
BZOJ 2429: [HAOI2006]聪明的猴子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 877 Solved: 566[Submit][ ...
- [原]携程预选赛A题-聪明的猴子-GCD+DP
题目: 聪明的猴子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- 【解题报告】[动态规划] CodingTrip - 携程编程大赛 (预赛第一场)- 聪明的猴子
原题: 聪明的猴子 Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Problem D ...
- 最小生成树——[HAOI2006]聪明的猴子
题目:[HAOI2006]聪明的猴子 描述: [题目描述] 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着, 猴子不会游泳,但跳 ...
- BZOJ 2429: [HAOI2006]聪明的猴子( MST )
水题, 求MST即可. -------------------------------------------------------------------------------- #includ ...
- 2429: [HAOI2006]聪明的猴子
2429: [HAOI2006]聪明的猴子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 448 Solved: 309[Submit][Statu ...
随机推荐
- jdbc与Statement接口
Statement接口引入 使用Statement接口实现添加数据操作 使用Statement接口实现更新数据操作 使用Statement接口实现删除数据操作
- webapp 增加 springmvc框架 支持
1.通过maven创建一个webapp项目,并在IDEA 中增加smart tomcat的插件. 2.然后在pom文件中添加springmvc的依赖 <!-- ServletAPI --> ...
- linux系统安装谷歌浏览器设置开机自动启动并打开指定页面
要在Linux系统上安装Google Chrome浏览器,可以按照以下步骤: 下载Google Chrome浏览器的安装包,你可以从Google的官方网站或者第三方下载站点上获取. 解压缩安装包并 ...
- MFC程序运行原理初探
几年前,写过一段时间的MFC,但是只知其然不知其所以然,最近闲来无事,研究了一下MFC程序的运行顺序,特此记录一下. 首先,如果我们创建一个MFC程序的话,首先会自动生成一个CWinApp的子类,程序 ...
- Qt 串口相关配置
QSerialPort M_serialPort; QSerialPortInfo M_SerialPortInfo; void MainWindow::on_M_portNumComboBox_cu ...
- hdrp package导入工程
补充: 可以直接把包提出来放一个单独文件夹 然后在package manager中load from disk,跟下面手动改效果没区别 如果发现有各种引用丢失,在工程内对包reimport下 1 需要 ...
- iverilog_makefile
makefile run: iverilog -g2005-sv -I ../inc -s tb -f filelist -o kout sim: vvp kout flist: find ../rt ...
- mybatis核心配置文件—mappers标签设置映射文件
<!-- 加载映射文件 --> <mappers> <!--<mapper resource="mappers/UserMapper.xml"& ...
- lg9035题解
考虑枚举\(a_{n-1}=l\),根据题意\(l\leq a_n\leq k+1-l\),这说明\(a_n\)有\(k+1-2l\)种取值. 令\(b_i=a_i-a_{i-1}\),则\(b_1\ ...
- 方法综合练习:out、params、ref
using System; namespace ConsoleApp1 { class Program { /// <summary> /// 求两个参数之间的最大值 /// </s ...