zoukankan      html  css  js  c++  java
  • [并查集]JZOJ 5904 刺客信条

    Description

              故事发生在1486 年的意大利,Ezio 原本只是一个文艺复兴时期的贵族,后来因为家族成员受到圣殿骑士的杀害,决心成为一名刺客。最终,凭借着他的努力和出众的天赋,成为了杰出的刺客大师。刺客组织在他的带领下,为被剥削的平民声张正义,赶跑了原本统治意大利的圣殿骑士首领-教皇亚历山大六世。在他的一生中,经历了无数次惊心动魄、扣人心弦的探险和刺杀。
            这次的故事就是他暗杀一位作恶多端的红衣主教。红衣主教可以吸取他周围人的生命力量,而他的红衣教徒也拥有这个力量。红衣主教的家是一个x*y 的长方形房间,也就是说,他的家的四个角坐标分别为(0,0)(x,0)(0,y)(x,y)。教堂的门在(0,0) ,而红衣主教就在 (x,y)的卧室休息。他的家中还有n个守护着他的红衣教徒,站在(ai,bi)。Ezio想要趁主教休息时,从门进入潜入到他的卧室刺杀他,因为主教休息时会脱下红衣,这样吸取生命的力量就消失了。可是守卫他的红衣教徒依然很危险,离红衣教徒太近就会被吸取生命。因此,Ezio想知道,在能刺杀主教的前提,从门到他的卧室的路上,他最远和离他最近的红衣教徒保持多远的距离。注意:教徒都在房间里。
     

    Input

    第一行三个整数x,y,n。之后n行,每行两个整数ai,bi ,意义见题目描述。

    Output

    一行一个数D,表示Ezio能保持的最大距离,保留两位小数。
     

    Sample Input

    10 20 2
    3 3
    6 14

    Sample Output

    3.00
    
    
    
    样例说明
    贴着墙走
     

    Data Constraint

    数据范围
    对 10%的数据n<=10,
     对 30%的数据n<=100
    对 100%的数据n<=2000
    保证输入合法,x,y属于[1,10^6].

    分析

    连通性问题

    如果底边和左边或者左边和右边连通和上边和底边连通或者上边和右边连通,则走不通

    那么我们二分一下半径,每次n^2暴力每个点对,用并查集判断是否连通

    然后最后,cmath信不得,我把sqrt去掉多拿了10分,把pow去掉又多拿了10分,就AC了

    //#pragma GCC optimize(2) 
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    const int N=2e3+10;
    struct Point {
        double x,y;
    }a[N];
    double x,y;
    int f[N],rk[N];
    int n;
    
    int Get_F(int x) {return x==f[x]?x:f[x]=Get_F(f[x]);}
    
    void Merge(int x,int y) {
        int i=Get_F(x),j=Get_F(y);
        if (rk[i]<rk[j]) {
            rk[j]=max(rk[j],rk[i]+1);
            f[i]=j;
        }
        else {
            rk[i]=max(rk[i],rk[j]+1);
            f[j]=i;
        }
    }
    
    int main() {
        freopen("AC.in","r",stdin);
        freopen("AC.out","w",stdout);
        scanf("%lf%lf%d",&x,&y,&n);
        for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
        double l=0,r=1e6,mid;
        while (r-l>1e-3) {
            mid=(l+r)/2.0;
            for (int i=1;i<=n+4;i++) f[i]=i,rk[i]=1;
            for (int i=1;i<=n-1;i++)
                for (int j=i+1;j<=n;j++)
                    if ((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)<mid*mid*4.0)
                        Merge(i,j);
            for (int i=1;i<=n;i++) {
                if (a[i].x<mid) Merge(i,n+1);
                if (a[i].y<mid) Merge(i,n+2);
                if (x-a[i].x<mid) Merge(i,n+3);
                if (y-a[i].y<mid) Merge(i,n+4);
            }
            int f1=Get_F(n+1),f2=Get_F(n+2),f3=Get_F(n+3),f4=Get_F(n+4);
            if (f1==f2||f1==f3||f2==f4||f3==f4) r=mid;
                else l=mid+1e-3;
        }
        printf("%.2lf",mid);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    EL表达式取整问题
    win7下安装 oracle 10g:permission denied
    jsp引用servlet生成的验证码..
    控制span的width属性
    Spring读书笔记Spring的Bean之设置Bean值
    如何将WEBINF下的jsp页面插入在frameset中
    一友人说有急事要回家,看发生何事
    占淘宝,今日无空,留存
    一人占工作调动
    代码恶心度判定法则
  • 原文地址:https://www.cnblogs.com/mastervan/p/9791683.html
Copyright © 2011-2022 走看看