BZOJ 2429 [HAOI2006]聪明的猴子

BZOJ 2429 [HAOI2006]聪明的猴子

【题解】

先跑一边最小生成树,记录树上最大的边权,然后对于每只猴子判断其跳跃距离是否大于等于最大边权即可。同时为了避免小数的麻烦,边权保留勾股定理后的平方结果,把猴子的跳跃距离平方一下,因为都是非负数,平方一下不改变大小关系。

BZOJ 2429 [HAOI2006]聪明的猴子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 }
View Code

相关推荐