您的位置:首页 > 其它

BZOJ2429[HAOI2006]聪明的猴子(最小生成树)

2017-09-21 20:38 281 查看
题目描述:给出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

题目分析:将树两两建边,权值为两点间的距离,然后用最小生成树kruskal算法求出最短路径中的最长边,再判断每只猴子能不能跳过这个最长边的距离。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
int q[510],x[1100],y[1100];
int fa[1100000];
struct node
{
int x,y;double d;
}a[1100000];int len;
int cmp(const void *xx
4000
,const void *yy)
{
node n1=*(node *)xx;
node n2=*(node *)yy;
if(n1.d>n2.d) return 1;
if(n1.d<n2.d) return -1;
return 0;
}
int findfa(int x)
{
if(fa[x]==x) return x;
else
{
fa[x]=findfa(fa[x]);
return fa[x];
}
}
int main()
{
int n,m;scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&q[i]);
len=0;
scanf("%d",&m);
for(int i=1;i<=m;i++) scanf("%d%d",&x[i],&y[i]);
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
{
if(i!=j) {len++;a[len].x=i;a[len].y=j;a[len].d=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));}
}
}
qsort(a+1,len,sizeof(node),cmp);
for(int i=1;i<=m;i++) fa[i]=i;
int t=0;double maxx=0;
for(int i=1;i<=len;i++)
{
int fx,fy;
fx=findfa(a[i].x);
fy=findfa(a[i].y);
if(fa[fx]!=fa[fy])
{
maxx=max(maxx,a[i].d);
fa[fy]=fx;
t++; if(t==m-1) break;
}
}
int sum=0;
for(int i=1;i<=n;i++)
{
if(q[i]>=maxx) sum++;
}
printf("%d\n",sum);
return 0;
}


注意一下数据的大小,不要把数组开小。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: