BZOJ 2429 [HAOI2006]聪明的猴子
【题解】
先跑一边最小生成树,记录树上最大的边权,然后对于每只猴子判断其跳跃距离是否大于等于最大边权即可。同时为了避免小数的麻烦,边权保留勾股定理后的平方结果,把猴子的跳跃距离平方一下,因为都是非负数,平方一下不改变大小关系。
1 #include<cstdio> 2 #include<algorithm> 3 #define N 1010 4 #define rg register 5 using namespace std; 6 int n,m,mx,tot,ans,cnt,dis[N],fa[N]; 7 struct rec{ 8 int u,v,dis; 9 }a[N*N]; 10 struct point{ 11 int x,y; 12 }p[N]; 13 inline int read(){ 14 int k=0,f=1; char c=getchar(); 15 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 16 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 17 return k*f; 18 } 19 inline bool cmp(rec a,rec b){return a.dis<b.dis;} 20 inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} 21 int main(){ 22 m=read(); 23 for(rg int i=1;i<=m;i++) dis[i]=read(),dis[i]*=dis[i]; 24 n=read(); 25 for(rg int i=1;i<=n;i++){ 26 p[i].x=read(),p[i].y=read(); 27 } 28 for(rg int i=1;i<n;i++) 29 for(rg int j=i+1;j<=n;j++) 30 a[++tot]=(rec){i,j,(p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)}; 31 sort(a+1,a+1+tot,cmp); 32 for(rg int i=1;i<=n;i++) fa[i]=i; 33 for(rg int i=1;i<=tot;i++){ 34 int u=find(a[i].u),v=find(a[i].v); 35 if(u!=v) mx=max(mx,a[i].dis),fa[u]=v,cnt++; 36 if(cnt>=n-1) break; 37 } 38 for(rg int i=1;i<=m;i++) if(dis[i]>=mx) ans++; 39 printf("%d\n",ans); 40 return 0; 41 }