[HAOI2006] 聰明的猴子
阿新 • • 發佈:2018-04-01
stdin scan 多少 truct struct bsp can brush freopen
求有多少只猴子可以在所有樹上跳來跳去。
求出圖的最小生成樹,因為最小生成樹是一顆瓶頸生成樹(樹上最大邊權最小),記錄下這棵樹的最大邊權。因為猴子是一條一條邊跳的,所以只要猴子能越過這條邊,就能越過所有的邊,進而到達所有的樹。
// q.c #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int M=1000+10; struct Edge { int u,v; double w; Edge():u(0),v(0),w(0) {} bool operator < (const Edge &A) const { return w<A.w; } }ed[M*M>>1]; int m,n,cnt,w[M],x[M],y[M],fa[M],ans; void add_edge(int a,int b,double c) { ed[++cnt].u=a,ed[cnt].v=b,ed[cnt].w=c; } double dis(int a,int b) { return sqrt((x[a]-x[b])*(x[a]-x[b])*1.0+(y[a]-y[b])*(y[a]-y[b])); } int find(int a) { return fa[a]==a?a:fa[a]=find(fa[a]); } double kruscal() { sort(ed+1,ed+cnt+1); int k=1; double maxx=0; for(int i=1;i<=cnt;i++) { Edge p=ed[i]; int fu=find(p.u); int fv=find(p.v); if(fu==fv) continue; fa[fu]=fv; ++k; if(k==n) { // ~~~if(k==n-1)~~~ maxx=p.w; break; } } return maxx; } int main() { freopen("monkey.in","r",stdin); freopen("monkey.out","w",stdout); scanf("%d",&m); for(int i=1;i<=m;i++) scanf("%d",&w[i]); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]),fa[i]=i; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) add_edge(i,j,dis(i,j)); double maxx=kruscal(); for(int i=1;i<=m;i++) if(w[i]>=maxx) ans++; printf("%d\n",ans); return 0; }
[HAOI2006] 聰明的猴子