BZOJ2429: [HAOI2006]聪明的猴子
【传送门:BZOJ2429】
简要题意:
给出n只猴子以及n只猴子的跳跃距离,给出m棵树以及m棵树的坐标,每只猴子只能跳向与自己所在的树的欧几里得距离<=自己的跳跃距离的树,求出有多少只猴子能够通过跳跃到达所有的树
题解:
最小生成树有个定义就是最小生成树中的最大边一定最小,所以用最小生成树来做
将m棵树互相连边,然后构造最小生成树,然后记录最大边的边权,只要猴子的跳跃距离>=最大边的边权,那就说明这只猴子能够到达所有的树
参考代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; struct node { int x,y,next;double d; }a[1100000];int len,last[1100]; void ins(int x,int y,double d) { len++; a[len].x=x;a[len].y=y;a[len].d=d; a[len].next=last[x];last[x]=len; } int fa[1100]; int findfa(int x) { if(x!=fa[x]) fa[x]=findfa(fa[x]); return fa[x]; } double p[510]; double x[1100],y[1100]; bool cmp(node n1,node n2) { return n1.d<n2.d; } int main() { int n,m; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf",&p[i]); scanf("%d",&m); len=0;memset(last,0,sizeof(last)); for(int i=1;i<=m;i++) scanf("%lf%lf",&x[i],&y[i]); for(int i=1;i<=m;i++) for(int j=i+1;j<=m;j++) ins(i,j,sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))); double mx=0.0; sort(a+1,a+len+1,cmp); for(int i=1;i<=m;i++) fa[i]=i; int tot=0; for(int i=1;i<=len;i++) { int fx=findfa(a[i].x),fy=findfa(a[i].y); if(fx!=fy) { mx=max(mx,a[i].d); fa[fx]=fy; tot++;if(tot==m-1) break; } } int ans=0; for(int i=n;i>=1;i--) if(p[i]>=mx) ans++; printf("%d\n",ans); return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚