D剖练习题,没什么好讲的。看问题显然是求Voronoi图,然而我们要用的只有V图中点的相邻关系,直接用D剖求一下就行了。
代码:
#include
#define ll long long
#define re register
#define db double
#define cs const
namespace IO{
inline char gc(){
static cs int Rlen=1<<22|1;static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}template<typename T>T get_integer(){
char c;bool f=false;while(!isdigit(c=gc()))f=c=='-';T num=c^48;
while(isdigit(c=gc()))num=((num+(num<<2))<<1)+(c^48);return f?-num:num;
}inline int gi(){return get_integer<int>();}
}using namespace IO;
using std::cerr;
using std::cout;
cs int N=3e3+7;
struct Pnt{
db x,y;Pnt(){}Pnt(db _x,db _y):x(_x),y(_y){}
friend Pnt operator+(cs Pnt &a,cs Pnt &b){return Pnt(a.x+b.x,a.y-b.y);}
friend Pnt operator-(cs Pnt &a,cs Pnt &b){return Pnt(a.x-b.x,a.y-b.y);}
friend db operator*(cs Pnt &a,cs Pnt &b){return a.x*b.y-a.y*b.x;}
friend db dot(cs Pnt &a,cs Pnt &b){return a.x*b.x+a.y*b.y;}
db len()cs{return sqrt(x*x+y*y);}
};
struct pt{
db x,y,z;pt(){}pt(db _x,db _y,db _z):x(_x),y(_y),z(_z){}
friend pt operator+(cs pt &a,cs pt &b){return pt(a.x+b.x,a.y+b.y,a.z+b.z);}
friend pt operator-(cs pt &a,cs pt &b){return pt(a.x-b.x,a.y-b.y,a.z-b.z);}
friend pt operator*(cs pt &a,cs pt &b){return pt(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-b.x*a.y);}
friend db dot(cs pt &a,cs pt &b){return a.x*b.x+a.y*b.y+a.z*b.z;}
pt operator-()cs{return pt(-x,-y,-z);}
db len()cs{return sqrt(x*x+y*y+z*z);}
};
inline db crs(cs Pnt &a,cs Pnt &b,cs Pnt &c){
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
inline pt crs(cs pt &a,cs pt &b,cs pt &c){
return (b-a)*(c-a);
}
inline pt trans(cs Pnt &a){
return pt(a.x,a.y,a.x*a.x+a.y*a.y);
}
inline bool incir(cs Pnt &D,cs Pnt &A,cs Pnt &B,cs Pnt &C){
pt a=trans(A),b=trans(B),c=trans(C),d=trans(D);
pt dir=crs(a,b,c);if(dir.z>0)dir=-dir;return dot(dir,d-a)>0;
}
cs int M=N<<3|7;
int n;db X,Y;
Pnt p[N];
int bin[M],tot;
int pr[M],nx[M];
int to[M],rev[M];
inline int ins_pr(int u,int v){
int e=bin[++tot];
pr[e]=pr[u],nx[e]=u;
nx[pr[e]]=e,pr[u]=e;
to[e]=v;return e;
}
inline int ins_nx(int u,int v){
int e=bin[++tot];
nx[e]=nx[u],pr[e]=u;
pr[nx[e]]=e,nx[u]=e;
to[e]=v;return e;
}
inline void del(int e){
pr[nx[e]]=pr[e];
nx[pr[e]]=nx[e];
bin[tot--]=e;
}
inline db crs(int a,int b,int c){
return crs(p[a],p[b],p[c]);
}
inline bool incir(int d,int a,int b,int c){
return incir(p[d],p[a],p[b],p[c]);
}
void delaunay(int l,int r){
if(l==r)return ;
if(l+1==r){
int el=ins_nx(l,r);
int er=ins_pr(r,l);
rev[el]=er,rev[er]=el;
return ;
}int mid=(l+r)>>1,tp=0;static int st[N];
delaunay(l,mid);delaunay(mid+1,r);
for(int re i=l;i<=r;++i){
while(tp>1&&crs(st[tp-1],st[tp],i)<0)--tp;
st[++tp]=i;
}int nl=0,nr=0;
for(int re i=1;i<=tp;++i)
if(st[i]<=mid&&st[i+1]>mid)
{nl=st[i],nr=st[i+1];break;}
int sl,sr;
for(sl=pr[nl];sl!=nl;sl=pr[sl])
if(crs(nl,nr,to[sl])>=0)break;
for(sr=nx[nr];sr!=nr;sr=nx[sr])
if(crs(nr,nl,to[sr])<=0)break;
int el=ins_nx(sl,nr),er=ins_pr(sr,nl);
rev[el]=er,rev[er]=el;
while(true){
bool cl=false,cr=false;
for(;sl!=nl;sl=pr[sl]){
if(crs(nl,nr,to[sl])<=0){
if(p[to[sl]].x>=p[nl].x)continue;
break;
}
if(pr[sl]!=nl&&incir(to[pr[sl]],nl,nr,to[sl]))
del(rev[sl]),del(sl);
else {cl=true;break;}
}
for(;sr!=nr;sr=nx[sr]){
if(crs(nr,nl,to[sr])>=0){
if(p[to[sr]].x<p[nr].x)continue;
break;
}
if(nx[sr]!=nr&&incir(to[nx[sr]],nr,nl,to[sr]))
del(rev[sr]),del(sr);
else {cr=true;break;}
}
if(!cl&&!cr)break;
if(!cr||(cl&&!incir(to[sr],nl,nr,to[sl]))){
nl=to[sl];
for(sl=pr[nl];sl!=nl;sl=pr[sl])
if(crs(nl,nr,to[sl])>=0||p[to[sl]].x<p[nl].x)break;
el=ins_nx(sl,nr),er=ins_pr(sr,nl);
rev[el]=er,rev[er]=el;
}else {
nr=to[sr];
for(sr=nx[nr];sr!=nr;sr=nx[sr])
if(crs(nr,nl,to[sr])<=0||p[to[sr]].x>p[nr].x)break;
el=ins_nx(sl,nr),er=ins_pr(sr,nl);
rev[el]=er,rev[er]=el;
}
}
}
struct edge{int u,v;db w;};
std::vector<edge> E;int fa[N];
inline int gf(int u){while(u!=fa[u])u=fa[u]=fa[fa[u]];return u;}
void Main(){
n=gi(),X=gi(),Y=gi();
for(int re i=1;i<=n;++i)p[i].x=gi(),p[i].y=gi();
tot=n;for(int re i=1;i<M;++i)bin[i]=i;
for(int re i=1;i<=n;++i)pr[i]=nx[i]=i;
std::sort(p+1,p+n+1,[](cs Pnt &a,cs Pnt &b){
return a.x==b.x?(a.y<b.y):(a.x<b.x);
});delaunay(1,n);for(int re i=1;i<=n;++i){
E.push_back({i,n+1,std::min(p[i].x-1,Y-p[i].y)});
E.push_back({i,n+2,std::min(p[i].y-1,X-p[i].x)});
for(int re e=nx[i];e!=i;e=nx[e])if(to[e]>i)
E.push_back({i,to[e],(p[i]-p[to[e]]).len()*0.5});
}std::sort(E.begin(),E.end(),[](cs edge &a,cs edge &b){return a.w<b.w;});
for(int re i=1;i<=n+2;++i)fa[i]=i;
for(auto &e:E)if(gf(e.u)!=gf(e.v)){
fa[gf(e.u)]=gf(e.v);
if(gf(n+1)==gf(n+2)){
printf("%.2lf\n",e.w);return ;
}
}
}
void file(){
#ifdef zxyoi
freopen("dis.in","r",stdin);
#endif
}
signed main(){file();Main();return 0;}