10.22T1 二分+并查集

6028 -- 【2020级互测D8T1】⑩⑨⑥的穿行

 

Description

朝比奈实 玖 瑠 ,使用TPDD进行时间穿行的未来人。
由于这项技术过于暴力 (简单来说就是在时间平面上打洞),加之春日带来的资讯爆炸
使得堆叠的时间平面彻底截断,导致实玖瑠进行穿行需要冒一定的风险。
复杂的时间穿行过程可以抽象为从平面x轴的正无穷远处走向负无穷远。TPDD的功率显然是有限的,所以实玖瑠只能够在平面y= 的直线与X轴所夹的部分里移动。TPDD的移动方式非常的怪异,它会生成一个直径为 的圆来保护使用者,并且从正无穷远处向负无穷远处移动,直径越大,能量越足,移动速度也就最快。但是,时间穿行的风险就在于时间平面上有许多特异点,一旦被卷入其中,就再也不能回到原来的时间点。在从正无穷远走向负无穷远的过程中,圆可以任意的移动,但是不能碰到特异点和越过边界。
实玖瑠已经了解到,在她将要进行移动的部分平面上,有N个特异点,第i个点的坐标是xi,yi 。为了能够在保证安全的情况下尽快完成时间穿行,她需要设定尽量大的直径 。
但是1096只是一个萌物,这样的问题对她来说太困难了,所以请你帮帮她吧!

Input

输入文件共N+1行。
第一行包括两个整数N,L 。
接下来N行,每行两个整数xi,yi

Output

输出文件仅一行,表示最大的直径。为了防止精度误差,请输出保留三位小数的结果。

Sample Input

1 5
2 2

Sample Output

3.000 【输入输出样例1说明】 显然可以发现,从唯一一个特异点靠L的方向可以通过直径为3的圆

Hint

【数据规模与约定】
对于 30% 的数据,N<=3 。
对于 60% 的数据,N<=80 。
对于 100% 的数据,1<=N<=500,1<=yi<L<10000,-10000<=xi<=10000
 
 
 
二分圆的大小,把两点以及到边缘小于这个距离的合并,如果上下界合并在了一起显然就没有路径
code:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #define N 100006
 6 using namespace std;
 7 double eps=1e-6;
 8 int fa[N];
 9 struct node {
10     int x,y;
11 } e[N];
12 int n;
13 double L;
14 int find(int x){
15     if(x!=fa[x])return fa[x]=find(fa[x]);
16     return fa[x];
17 }
18 void merge(int x,int y){
19     int f1=find(x),f2=find(y);
20     if(f1!=f2){
21         fa[f1]=f2;
22     }
23 }
24 double sq(double x){
25     return x*x;
26 }
27 double getdis(int i,int j){
28     return sqrt(sq(e[i].x-e[j].x)+sq(e[i].y-e[j].y));
29 }
30 bool check(double mid) {
31     for(int i=0;i<=n+1;i++)fa[i]=i;
32     for(int i=1; i<=n; i++){
33         for(int j=i+1;j<=n;j++){
34             if(getdis(i,j)<mid)merge(i,j);
35         }
36         if(e[i].y<mid)merge(0,i);
37         if(L-e[i].y<mid)merge(n+1,i);
38     }
39     if(find(0)==find(n+1))return false;
40     return true;
41 }
42 int main() {
43     cin>>n>>L;
44     for(int i=1; i<=n; i++)
45         cin>>e[i].x>>e[i].y;
46     double l=0,r=L,ans;
47     while(r-l>=eps) {
48         double mid=(l+r)/2;
49     //    cout<<l<<" "<<r<<" "<<mid<<'\n';
50         if(check(mid))l=mid,ans=mid;
51         else r=mid;
52     }
53     printf("%.3f",ans);
54     return 0;
55 }

over

posted @ 2018-10-22 20:45  saionjisekai  阅读(127)  评论(0编辑  收藏  举报