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;
}

 

posted @ 2019-03-27 12:49  冥想选手  阅读(156)  评论(0编辑  收藏  举报