【bzoj2429】[HAOI2006]聪明的猴子(图论--最小瓶颈生成树 模版题)

题意:有M只猴子,他们的最大跳跃距离为Ai。树林中有N棵树露出了水面,给出了它们的坐标。问有多少只猴子能在这个地区露出水面的所有树冠上觅食。

解法:由于要尽量多的猴子能到达所有树冠,便用Kruskal求一次MST最小生成树,也就得到了最大边最小的最小瓶颈生成树。在用这个最大边权计算合法的猴子树。

P.S.由于没有那些一下子输入几十万的数据,所以读优和不读优差别不大。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<iostream>
 6 using namespace std;
 7 
 8 const int M=510,N=1010,D=2010;
 9 int n,m,len;
10 int a[M],fa[N];
11 struct node{int x,y;}b[N];
12 struct edge
13 {
14     int x,y,d;
15     edge() {}
16     edge(int i,int j,int k) {x=i;y=j;d=k;}
17 }
18 e[N*N/2];
19 
20 int sq_dist(int i,int j) {return (b[i].x-b[j].x)*(b[i].x-b[j].x)+(b[i].y-b[j].y)*(b[i].y-b[j].y);}
21 bool cmp(edge x,edge y) {return x.d<y.d;}
22 int ffind(int x)
23 {
24     if (fa[x]!=x) fa[x]=ffind(fa[x]);
25     return fa[x];
26 }
27 int Kruskal()
28 {
29     int i,j,k=0;
30     for (i=1;i<=n;i++) fa[i]=i;
31     sort(e+1,e+1+len,cmp);
32     for (i=1;i<=len;i++)
33     {
34       int fx=ffind(e[i].x),fy=ffind(e[i].y);
35       if (fx!=fy)
36       {
37         fa[fx]=fy,k++;
38         if (k==n-1) return e[i].d;
39       }
40     }
41 }
42 int read()
43 {
44     char c=getchar();
45     int x=0,t=1;
46     while (c>'9'||c<'0') {if (c=='-') t=-1;c=getchar();}
47     while (c<='9'&&c>='0') {x=x*10+(c-'0');c=getchar();}
48     return x*t;
49 }
50 int main()
51 {
52     int i,j,k;
53     m=read();
54     for (i=1;i<=m;i++) a[i]=read();
55     n=read();
56     for (i=1;i<=n;i++) 
57       b[i].x=read(),b[i].y=read();
58     len=0;
59     for (i=1;i<=n;i++)
60       for (j=i+1;j<=n;j++)
61         e[++len]=edge(i,j,sq_dist(i,j));
62     int mx=Kruskal(),cnt=0;
63     for (i=1;i<=m;i++)
64       if (a[i]*a[i]>=mx) cnt++;
65     printf("%d\n",cnt);
66     return 0;
67 }

 

posted @ 2016-11-03 14:20  konjac蒟蒻  阅读(522)  评论(0编辑  收藏  举报