[BZOJ2429][HAOI2006]聪明的猴子(最小生成树)

性质:最小生成树上任意两点间的最大边权,一定是这两点间所有路径的最大边权中最小的。证明显然。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 5 using namespace std;
 6 
 7 const int N=1010,M=1000010;
 8 int n,m,tot,ans,mx,k,a[N],fa[N];
 9 struct P{ int x,y; }p[N];
10 struct E{ int u,v,w; }e[M];
11 bool operator <(const E &a,const E &b){ return a.w<b.w; }
12 int sqr(int x){ return x*x; }
13 int get(int x){ return (fa[x]==x) ? x : fa[x]=get(fa[x]); }
14 
15 int main(){
16     scanf("%d",&m);
17     rep(i,1,m) scanf("%d",&a[i]);
18     scanf("%d",&n);
19     rep(i,1,n) scanf("%d%d",&p[i].x,&p[i].y),fa[i]=i;
20     rep(i,1,n-1) rep(j,i+1,n) e[++tot]=(E){i,j,sqr(p[i].x-p[j].x)+sqr(p[i].y-p[j].y)};
21     sort(e+1,e+tot+1);
22     rep(i,1,tot){
23         int u=e[i].u,v=e[i].v;
24         if (get(u)==get(v)) continue;
25         k++; mx=max(mx,e[i].w);
26         if (k==n-1) break;
27         fa[get(u)]=get(v);
28     }
29     rep(i,1,m) if (sqr(a[i])>=mx) ans++;
30     printf("%d
",ans);
31     return 0;
32 }
原文地址:https://www.cnblogs.com/HocRiser/p/9890825.html