bzoj 2429: [HAOI2006]聪明的猴子 (最小生成树)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2429
思路:就是找最小生成树最大的一条边,最小生成树的性质,最后加入的那条边就是最大的
实现代码:
#include<bits/stdc++.h> using namespace std; const int M = 1e6 + 10; struct node{ int u,v,w; }e[M]; struct node1{ int x,y; }v[M]; int f[M],a[M]; bool cmp(node a,node b){ return a.w < b.w; } int Find(int x){ if(x == f[x]) return x; return f[x] = Find(f[x]); } int main() { int n,m,cnt = 0; cin>>n; for(int i = 1;i <= n;i ++){ cin>>a[i]; } cin>>m; for(int i = 1;i <= m;i ++){ cin>>v[i].x>>v[i].y; f[i] = i; } for(int i = 1;i <= m;i ++){ for(int j = i+1;j <= m;j ++){ e[++cnt].u = i; e[cnt].v = j; e[cnt].w = (v[i].x-v[j].x)*(v[i].x-v[j].x)+(v[i].y-v[j].y)*(v[i].y-v[j].y); } } sort(e+1,e+1+cnt,cmp); int mx = 0,tot= 0; for(int i = 1;i <= cnt;i ++){ int fx = Find(e[i].u),fy = Find(e[i].v); if(fx != fy){ f[fy] = fx; tot++; if(tot == m-1){ mx = e[i].w; break; } } } //cout<<mx<<endl; int ans = 0; for(int i = 1;i <= n;i ++){ if(a[i]*a[i] >= mx) ans++; } cout<<ans<<endl; }