这题可以二分,设答案为mid,将问题转化为纵坐标为[mid,m-mid]之间的,点变成半径为mid的圆,看上面是否能连到下面。
80分:并查集做法。(然而我是这么做的,我直接存储该圆与哪一边连通,如果一个圆既与上面连通,又与下面连通,那么mid过大,我不知道这么做为什么是错的,有大佬帮我看看为什么吗?我WA了3个点)(第一份代码是WA了的代码)
100分做法:不二分,考虑连最小生成树。k+2个点,但是很多条边。所以用Prim算法。然后答案即为k+1到k+2的路径上最长边/2。
Prim算法:设Dis[i]表示目前没有被选的点i与任何一个被选的点的最小距离。
然后每一次挑选一个Dis最小的点作为下一个被选的点。
#include
#include
#include
#include
#include
#define N 1000010
#define eps 0.0000005
#define DB double
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct point{
DB x,y;
};point pt[N];
int n,m,k;
int i,j;
DB l,r,l1,r1,mid,ans,temp;
int bel[N];
bool jie;
bool cmp(point a,point b){
return a.yreturn sqrt((X1-X2)*(X1-X2)+(Y1-Y2)*(Y1-Y2));
}
int main(){
freopen("starway.in","r",stdin);
freopen("starway.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
fo(i,1,k)scanf("%lf%lf",&pt[i].x,&pt[i].y);
sort(pt+1,pt+k+1,cmp);
ans=0;
l=0,r=(DB)m/2;
while(l<=r){
mid=(l+r)/2;
l1=mid;r1=m-mid;
memset(bel,0,sizeof(bel));
fo(i,1,k)
if(pt[i].y<=l1+mid) bel[i]=1;else break;
fd(i,k,1)
if(pt[i].y>=r1-mid) bel[i]=2;else break;
jie=0;
fo(i,1,k-1){
if(bel[i]==1){
fo(j,i+1,k){
temp=dis(pt[i].x,pt[i].y,pt[j].x,pt[j].y);
if(temp<=2*mid){
if(bel[j]==2){
jie=1;
break;
}
bel[j]=1;
}
}
}
if(jie)break;
}
if(jie)r=mid-eps;else ans=mid,l=mid+eps;
}
printf("%.8lf",ans);
return 0;
}
#include
#include
#include
#include
#include
#define N 6010
#define eps 0.000001
#define DB double
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct point{
DB x,y;
};point pt[N];
struct note{
int to,next;
DB val;
};note edge[N*2];
int n,m,k,tot;
int i,j,gx,gy,wz,x;
DB l,r,l1,r1,mid,ans,mx,temp;
DB a1,a2,a3,a4;
int a[N][5],f[N];
DB dis[N];
int head[N],pre[N];
bool jie[N],vis[N],p;
int read(){
int res=0,fh=1;char ch;
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')fh=-1,ch=getchar();
while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
return res;
}
void lb(int x,int y,DB z){
edge[++tot].to=y;
edge[tot].next=head[x];
edge[tot].val=z;
head[x]=tot;
}
DB getdis(int a,int b){
if(a>b)swap(a,b);
if(a==k+1&&b==k+2)return m;
if(b==k+1)return pt[a].y;
if(b==k+2)return m-pt[a].y;
return sqrt((pt[a].x-pt[b].x)*(pt[a].x-pt[b].x)+(pt[a].y-pt[b].y)*(pt[a].y-pt[b].y));
}
int get(int x){return(f[x]==x)?x:f[x]=get(f[x]);}
void dg(int x,int fa,DB v){
if(x==k+2){
ans=v;
return;
}
int i;
for(i=head[x];i;i=edge[i].next)
if(edge[i].to!=fa)dg(edge[i].to,x,max(v,edge[i].val));
}
int main(){
freopen("starway.in","r",stdin);
freopen("starway.out","w",stdout);
n=read();m=read();k=read();
fo(i,1,k){
gx=read();gy=read();
pt[i].x=(DB)gx;pt[i].y=(DB)gy;
}
ans=0;
memset(dis,127,sizeof(dis));
dis[k+1]=0;
fo(i,1,k+2){
wz=0,mx=2147483647;
fo(j,1,k+2)
if(dis[j]if(pre[wz])lb(pre[wz],wz,dis[wz]),lb(wz,pre[wz],dis[wz]);
vis[wz]=1;
fo(j,1,k+2)
if(!vis[j] && wz!=j){
temp=getdis(wz,j);
if(temp1,0,0);
ans/=2;
printf("%.8lf",ans);
return 0;
}