第1行为一个整数,表示猴子的个数M(2 ≤ M ≤ 500); 第2行为M个整数,依次表示猴子的最大跳跃距离(每个整数值在1--1000之间); 第3行为一个整数表示树的总棵数N(2 ≤ N ≤ 1000); 第4行至第N+3行为N棵树的坐标(横纵坐标均为整数,范围为:-1000--1000)。(同一行的整数间用空格分开)
包括一个整数,表示可以在这个地区的所有树冠上觅食的猴子数示例1
4 1 2 3 4 6 0 0 1 0 1 2 -1 -1 -2 0 2 2
3
对于40%的数据,保证有2≤N≤100,1≤M≤1002 \le N \le 100,1 \le M \le 1002≤N≤100,1≤M≤100 对于全部的数据,保证有2≤N≤1000,1≤M=5002 \le N \le 1000,1 \le M=5002≤N≤1000,1≤M=500
题意:每只猴子有不同的跳跃距离,问总共有多少只猴子可以跳到所有点。
就是问多少只猴子可以生成最小生成树
点数1000,说明边数1000000 / 2 = 500000。总共有500只猴子。
500 * 500000 = 2e7...
sort排序复杂度:mlogm = 1e6
//-------------------------代码---------------------------- //#define int ll const int N = 1e5+10; int n,m; int h[N]; struct node { int x,y,c; bool operator<(const node& x) const { return c < x.c; } } p[N]; V<node> q; int dis(int x,int y) { return (p[x].x - p[y].x) * (p[x].x - p[y].x) + (p[x].y - p[y].y) * (p[x].y - p[y].y); } int f[N]; int find(int x){return x == f[x]? x:f[x] = find(f[x]);} void solve() { // cin>>n>>m; cin>>m; fo(i,1,m)cin>>h[i]; cin>>n; fo(i,1,n) { int x,y;cin>>x>>y; p[i] = {x,y}; } fo(i,1,n) { fo(j,i+1,n) { q.pb({i,j,(int)sqrt(dis(i,j))}); } } sort(all(q)); int ans = 0; fo(i,1,m) { int cnt = n - 1; fo(i,1,n) f[i] = i; for(auto it:q) { if(it.c > h[i] || cnt == 0) break; int a = it.first,b = it.second; if(find(a) != find(b)) { f[find(a)] = find(b); cnt -- ; } } // db(cnt) if(!cnt) ans ++ ; } cout<<ans<<endl; } void main_init() {} signed main(){ AC();clapping();TLE; cout<<fixed<<setprecision(12); main_init(); // while(cin>>n,n) // while(cin>>n>>m,n,m) // int t;cin>>t;while(t -- ) solve(); // {solve(); } return 0; } /*样例区 */ //------------------------------------------------------------