[bzoj2429][最小生成树]聪明的猴子

本文探讨了一个有趣的猴子觅食问题,通过利用最小生成树算法来解决该问题。该问题要求找出能到达所有树冠觅食的猴子数量,涉及到图论中的经典算法。

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

Sample Output

3

HINT

2<=N <= 1000,1<=M=500

题解

最近某些烦心事搞得心情极其糟糕状态极其差
题意就是让你找到一个能使这些点全部联通的图,这个图中的最大边权最小。
为什么最大边权一定要最小??我们假设一个图,其他边都比在标准图中的对应边权要小,但是最大边比在标准图中的对应边权大。很明显,就算你能到达其他点,这个最大边连的点可能是不能到达的。但是在标准图中,尽管有些边你可能跳的很吃力(边权大跳跃能力小),但是只要能过去最大的那个边,其他都能过去
那不就是最小生成树嘛。。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
struct node
{
    int x,y;double c;
}a[1110000];int len;
void ins(int x,int y,double c)
{
    len++;
    a[len].x=x;a[len].y=y;a[len].c=c;
}
bool cmp(node n1,node n2){return n1.c<n2.c;}
int fa[1100];
int findfa(int x)
{
    if(fa[x]!=x)fa[x]=findfa(fa[x]);
    return fa[x];
}
double dx[1100],dy[1100];
double l[1100];
int n,m;
double dis(int u,int v){return sqrt((dx[u]-dx[v])*(dx[u]-dx[v])+(dy[u]-dy[v])*(dy[u]-dy[v]));}
int main()
{
    scanf("%d",&m);
    for(int i=1;i<=m;i++)scanf("%lf",&l[i]);
    scanf("%d",&n);
    len=0;
    for(int i=1;i<=n;i++)scanf("%lf%lf",&dx[i],&dy[i]);
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)ins(i,j,dis(i,j));
    sort(a+1,a+1+len,cmp);
    for(int i=1;i<=n;i++)fa[i]=i;
    int cnt=n;double tmp;
    for(int i=1;i<=len;i++)
    {
        int p=findfa(a[i].x),q=findfa(a[i].y);
        if(p!=q)
        {
            fa[p]=q;
            cnt--;tmp=a[i].c;
            if(cnt==1)break;
        }
    }
    int ans=0;
    for(int i=1;i<=m;i++)if(l[i]>=tmp)ans++;
    printf("%d\n",ans);
    return 0;
}
源码地址: https://pan.quark.cn/s/3916362e5d0a 在C#编程平台下,构建一个曲线编辑器是一项融合了图形用户界面(GUI)构建、数据管理及数学运算的应用开发任务。 接下来将系统性地介绍这个曲线编辑器开发过程中的核心知识点:1. **定制曲线面板展示数据曲线**: - 控件选用:在C#的Windows Forms或WPF框架中,有多种控件可用于曲线呈现,例如PictureBox或用户自定义的UserControl。 通过处理重绘事件,借助Graphics对象执行绘图动作,如运用DrawCurve方法。 - 数据图形化:通过线性或贝塞尔曲线连接数据点,以呈现数据演变态势。 这要求掌握直线与曲线的数学描述,例如两点间的直线公式、三次贝塞尔曲线等。 - 坐标系统与缩放比例:构建X轴和Y轴,设定坐标标记,并开发缩放功能,使用户可察看不同区间内的数据。 2. **在时间轴上配置多个关键帧数据**: - 时间轴构建:开发一个时间轴组件,显示时间单位刻度,并允许用户在特定时间点设置关键帧。 时间可表现为连续形式或离散形式,关键帧对应于时间轴上的标识。 - 关键帧维护:利用数据结构(例如List或Dictionary)保存关键帧,涵盖时间戳和关联值。 需考虑关键帧的添加、移除及调整位置功能。 3. **调整关键帧数据,通过插值方法获得曲线**: - 插值方法:依据关键帧信息,选用插值方法(如线性插值、样条插值,特别是Catmull-Rom样条)生成平滑曲线。 这涉及数学运算,确保曲线在关键帧之间无缝衔接。 - 即时反馈:在编辑关键帧时,即时刷新曲线显示,优化用户体验。 4. **曲线数据的输出**: - 文件类型:挑选适宜的文件格式存储数据,例如XML、JSON或...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值