zoukankan      html  css  js  c++  java
  • 洛谷P4047 [JSOI2010]部落划分

    题目

    https://www.luogu.com.cn/problem/P4047

    思路

    关键句:“使靠得最近的两个部落尽可能远离”,二分答案经典套路。

    那么我们关心的就是check函数怎么写了,事实上,由于(n)很小,我们完全可以(n^2)枚举每两个点是否能分在不同部落中,如果不能就在两个点间连一条边,

    再写个并查集维护下连通块,细节见代码,时间复杂度(n^2logx)(x是坐标的大致范围),注意精度问题。

    代码

    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #define eps 1e-4
    #define maxn 1001
    #define db double
    using namespace std;
    int n,k;
    struct point{
        int x,y;
        bool operator <(point t){
            return x<t.x;
        }
    } p[maxn];
    db dis(int i,int j){
        db x2,y2;
        x2=p[i].x-p[j].x;
        y2=p[i].y-p[j].y;
        return sqrt(x2*x2+y2*y2);
    }
    int fa[maxn];
    int getf(int x){
        if(fa[x]==x) return x;
        fa[x]=getf(fa[x]);
        return fa[x];
    }
    int merge(int a,int b){
        int f1=getf(a),f2=getf(b);
        if(f1==f2) return 0;
        else{
            fa[f2]=f1;
            return 1;
        }
    }
    bool check(db limit){
        int cnt=n,i,j;
        for(i=1;i<=n;++i)
            fa[i]=i;
        for(i=1;i<=n;++i){
            for(j=i+1;j<=n;++j){
                if(p[j].x-p[i].x>limit) break;
                if(dis(i,j)<=limit){
                    cnt-=merge(i,j);
                }
            }
        }
        return cnt>=k;
    }
    int main(){
        int i,j;
        db l=0,r=14200;
        scanf("%d%d",&n,&k);
        for(i=1;i<=n;++i)
            scanf("%d%d",&p[i].x,&p[i].y);
        sort(p+1,p+n+1);
        while(r-l>eps){
            db mid=(l+r)/2;
            if(check(mid)) l=mid;
            else r=mid;
        }
        printf("%.2lf",l);
        // system("pause");
        return 0;
    }
  • 相关阅读:
    python 函数嵌套
    python 函数对象
    python 函数参数
    python 连接MySQL报错及解决方案
    解决 No module named pip
    python 文件处理
    python
    python 元祖
    python 读取域名信息
    ubuntu 配置网卡,DNS, iptables
  • 原文地址:https://www.cnblogs.com/landmine-sweeper/p/14512618.html
Copyright © 2011-2022 走看看