满分做法:
其实就是二分+奶酪那个题,二分不合法的情况为左边界联通到下边界和右边界,上边界连接到下边界和右边界。
#include<queue>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
const int maxm=3100;
const double eps=1e-5;
int k,n,m,tot;
double xx[maxm],yy[maxm];
int q[maxm];
bool vis[maxm];
double ans,rr;
bool flag=0;
double dis(int x,int y)
{
return sqrt((xx[x]-xx[y])*(xx[x]-xx[y])+(yy[x]-yy[y])*(yy[x]-yy[y]));
}
void dfs(int x)
{
vis[x]=1;
if((n-xx[x]<rr)||(yy[x]-1.0<rr))
{
flag=1;
return;
}
for(int i=1;i<=k;i++)
{
if(vis[i]) continue;
if(dis(x,i)<2*rr)
{
dfs(i);
if(flag)
return;
}
}
}
bool check(double x)
{
tot=0;
rr=x;
flag=0;
for(int i=1;i<=k;i++)
{
vis[i]=0;
if((xx[i]-1.0<rr)||(m-yy[i]<rr))
q[++tot]=i;
}
for(int i=1;i<=tot;i++)
{
if(!vis[q[i]])
{
dfs(q[i]);
if(flag)
return 0;
}
}
return 1;
}
int main()
{
scanf("%d%d%d",&k,&n,&m);
for(int i=1;i<=k;i++)
scanf("%lf%lf",xx+i,yy+i);
double l=0,r=max(n,m);
while(l+eps<=r)
{
double mid=(l+r)/2.0;
if(check(mid))
{
ans=mid;
l=mid+eps;
}
else r=mid-eps;
}
printf("%.2lf\n",ans);
return 0;
}