bzoj2429: [HAOI2006]聰明的猴子


神tm的題。。。

眾所周知這題是最小生成樹的說。。還有大神說是最小瓶頸生成樹(%%%D飛了

結果我就亂搞了。

可以發現,假如一個跳的很遠的猴子無法到達全部,那么比他跳的近的猴子肯定不行的,那我想二分猴子咯,然后O(m^2)寬搜一波O(logn*m^2)還是能狗過去的,結果WA了,搞到數據才發現,wc,還有什么猴子都跳不過去的數據,然而我ans沒有初始化。。

#include<cstdio>
#include
<cstring>
#include
<cstdlib>
#include
<algorithm>
#include
<cmath>
using namespace std;

struct tree
{
int x,y;
}t[
1100];int m;
int n,a[510];

bool v[1100];
int list[1100];
int dis(tree n1,tree n2)
{
return (n1.x-n2.x)*(n1.x-n2.x)+(n1.y-n2.y)*(n1.y-n2.y);
}
bool check(int k)
{
memset(v,
false,sizeof(v));v[1]=true;
int head=1,tail=2,rea=1;list[1]=1;
while(head!=tail)
{
tree tno
=t[list[head]];
for(int i=1;i<=m;i++)
{
if(v[i]==false&&dis(tno,t[i])<=a[k]*a[k])
{
v[i]
=true;
rea
++;
list[tail]
=i;
tail
++;
}
}
head
++;
}
if(rea==m)return true;
else return false;
}
int main()
{
scanf(
"%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a
+1,a+n+1);

scanf(
"%d",&m);
for(int i=1;i<=m;i++)scanf("%d%d",&t[i].x,&t[i].y);

int l=1,r=n,ans=n+1;
while(l<=r)
{
int mid=(l+r)/2;
if(check(mid)==true)
{
ans
=mid;
r
=mid-1;
}
else l=mid+1;
}
printf(
"%d\n",n-ans+1);
return 0;
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com