BZOJ1821_Group部落划分_KEY

题目传送门

这是一道并查集的题目,相信很多人都看出来了。

用一个类似Kurskal的东西求出最近的最大值。

对于一些可以划分在同一个部落里的边,我们一定是优先选择短边合并。

code

/**************************************************************
    Problem: 1821
    User: yekehe
    Language: C++
    Result: Accepted
    Time:432 ms
    Memory:9136 kb
****************************************************************/
 
#include <bits/stdc++.h>
using namespace std;
int a[1001],b[1001];
int n,k,now,fa[1001];
double p(double x1,double x2,double y1,double y2){
    return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
double w[1001];
struct node{
    int x,y;
    double c;
}l[500001];
inline int cmp(node x,node y){return x.c<y.c;}
int getf(int x){return x==fa[x]?x:fa[x]=getf(fa[x]);}
int main(){
    scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%d%d",&a[i],&b[i]);
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                l[++now].x=i,l[now].y=j,l[now].c=p(a[i],a[j],b[i],b[j]);
    sort(l+1,l+now+1,cmp);
        for(int i=1;i<=n;i++)fa[i]=i;
    int ans=0,i;
        for(i=1;i<=now;i++){
            int x=getf(l[i].x),y=getf(l[i].y),c=l[i].c;
            if(x!=y){
                fa[x]=y;
                w[++ans]=c;
                if(ans==n-1)break;
            }
        }
    printf("%.2lf",sqrt(w[n-k+1]));
    return 0;
}

 

posted @ 2017-09-25 21:49  Cptraser  阅读(258)  评论(0编辑  收藏  举报