ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

1037 [HAOI2006]聪明的猴子 看有多少能到达所有点 最小生成树

2022-08-24 01:04:55  阅读:175  来源: 互联网

标签:le int cin 猴子 find HAOI2006 1037 1000


 链接:https://ac.nowcoder.com/acm/contest/26077/1037
来源:牛客网

题目描述

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

输入描述:

第1行为一个整数,表示猴子的个数M(2 ≤ M ≤ 500);
第2行为M个整数,依次表示猴子的最大跳跃距离(每个整数值在1--1000之间);
第3行为一个整数表示树的总棵数N(2 ≤ N ≤ 1000);
第4行至第N+3行为N棵树的坐标(横纵坐标均为整数,范围为:-1000--1000)。(同一行的整数间用空格分开)

输出描述:

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

输入

复制
4
1 2  3  4
6 
0 0
1 0
1 2
-1 -1
-2  0
2  2

输出

复制
3

备注:

对于40%的数据,保证有2≤N≤100,1≤M≤1002 \le N  \le 100,1 \le M \le 1002≤N≤100,1≤M≤100

对于全部的数据,保证有2≤N≤1000,1≤M=5002 \le N \le 1000,1 \le M=5002≤N≤1000,1≤M=500

分析

题意:每只猴子有不同的跳跃距离,问总共有多少只猴子可以跳到所有点。

就是问多少只猴子可以生成最小生成树

点数1000,说明边数1000000 / 2 = 500000。总共有500只猴子。

500 * 500000 = 2e7...

sort排序复杂度:mlogm = 1e6

//-------------------------代码----------------------------

//#define int ll
const int N = 1e5+10;
int n,m;
int h[N];

struct node {
    int x,y,c;
    bool operator<(const node& x) const {
        return c < x.c;
    }
} p[N];

V<node> q;

int dis(int x,int y) {
    return (p[x].x - p[y].x) * (p[x].x - p[y].x) + (p[x].y - p[y].y) * (p[x].y - p[y].y);
}
int f[N];
int find(int x){return x == f[x]? x:f[x] = find(f[x]);}

void solve()
{
//    cin>>n>>m;
    cin>>m;
    fo(i,1,m)cin>>h[i];
    
    cin>>n;
    fo(i,1,n) {
        int x,y;cin>>x>>y;
        p[i] = {x,y};
    }
    fo(i,1,n) {
        fo(j,i+1,n) {
            q.pb({i,j,(int)sqrt(dis(i,j))});
        }
    }
    sort(all(q));
    int ans = 0;
    fo(i,1,m) {
        int cnt = n - 1;
        fo(i,1,n) f[i] = i;
        for(auto it:q) {
            if(it.c > h[i] || cnt == 0) break;
            int a = it.first,b = it.second;
            if(find(a) != find(b)) {
                f[find(a)] = find(b);
                cnt -- ;
            }
        }
//         db(cnt)
        if(!cnt) ans ++ ;
    }
    cout<<ans<<endl;
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

标签:le,int,cin,猴子,find,HAOI2006,1037,1000
来源: https://www.cnblogs.com/er007/p/16618376.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有