#include #include #include #include const int CCC=20; const int RR=400; const int V=8000; const double eps=1e-7; const int N=65550; bool hash[N]; int st[N]; const double pi = acos(-1.0); int U[V],D[V]; int L[V],R[V]; int C[V]; int size,S[CCC],H[RR],n,m; int dir[17]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536}; struct node{ double x,y; }s[20]; struct point{ double x,y; }cnt,cnt1; double Dis(point a,point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } point Whirl(double cosl, double sinl, point a, point b) { b.x -= a.x; b.y -= a.y; point c; c.x = b.x * cosl - b.y * sinl + a.x; c.y = b.x * sinl + b.y * cosl + a.y; return c; } point inst(point u1,point u2,point v1,point v2) { point ans = u1; double t = ((u1.x - v1.x)*(v1.y - v2.y) - (u1.y - v1.y)*(v1.x - v2.x))/ ((u1.x - u2.x)*(v1.y - v2.y) - (u1.y - u2.y)*(v1.x - v2.x)); ans.x += (u2.x - u1.x)*t; ans.y += (u2.y - u1.y)*t; return ans; } point fun(point a,point b,double r) { double l=Dis(a,b); double ans=acos((l/2)/r); point k1=Whirl(cos(ans),sin(ans),a,b); point k2=Whirl(cos(ans),-sin(ans),b,a); point cent=inst(a,k1,b,k2); return cent; } void Link(int r,int c) { S[c]++;C[size]=c; U[size]=U[c];D[U[c]]=size; D[size]=c;U[c]=size; if(H[r]==-1) H[r]=L[size]=R[size]=size; else { L[size]=L[H[r]];R[L[H[r]]]=size; R[size]=H[r];L[H[r]]=size; } size++; } void remove(int c) { int i; for(i=D[c];i!=c;i=D[i]) L[R[i]]=L[i],R[L[i]]=R[i]; } void resume(int c) { int i; for(i=U[c];i!=c;i=U[i]) L[R[i]]=R[L[i]]=i; } int h() { int i,j,k,count=0; bool visit[20]; memset(visit,0,sizeof(visit)); for(i=R[0];i;i=R[i]) { if(visit[i]) continue; count++; visit[i]=1; for(j=D[i];j!=i;j=D[j]) { for(k=R[j];k!=j;k=R[k]) visit[C[k]]=1; } } return count; } int Dance(int k) { int i,j,Min,c; if(k+h()>m) return 0; if(!R[0]) return 1; for(Min=RR,i=R[0];i;i=R[i]) if(S[i]=left) { for(i=0;i<=n;i++) { S[i]=0; U[i]=D[i]=i; L[i+1]=i;R[i]=i+1; }R[n]=0; size=n+1; memset(H,-1,sizeof(H)); memset(hash,0,sizeof(hash)); mid=(left+right)/2; r=0; sum=0; for(i=1;i<=n;i++) { ansx=s[i].x;ansy=s[i].y; bit=0; for(j=1;j<=n;j++) if(dis(s[j].x,s[j].y,ansx,ansy)<=mid) bit+=dir[j-1]; if(!hash[bit]) {hash[bit]=1;st[++sum]=bit;} } for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { num=dis(s[i].x,s[i].y,s[j].x,s[j].y); if(num<2*mid) { a.x=s[i].x;a.y=s[i].y; b.x=s[j].x;b.y=s[j].y; cnt=fun(a,b,mid); ansx=(a.x+b.x)/2; ansy=(a.y+b.y)/2; cnt1.x=2*ansx-cnt.x; cnt1.y=2*ansy-cnt.y; bit=0; for(k=1;k<=n;k++) { if(k==i) {bit+=dir[i-1];continue;} if(k==j) {bit+=dir[j-1];continue;} if(dis(s[k].x,s[k].y,cnt.x,cnt.y)<=mid) bit+=dir[k-1]; } if(!hash[bit]) {hash[bit]=1;st[++sum]=bit;} bit=0; for(k=1;k<=n;k++) { if(k==i) {bit+=dir[i-1];continue;} if(k==j) {bit+=dir[j-1];continue;} if(dis(s[k].x,s[k].y,cnt1.x,cnt1.y)<=mid) bit+=dir[k-1]; } if(!hash[bit]) {hash[bit]=1;st[++sum]=bit;} } else if(num==2*mid) { ansx=(s[i].x+s[j].x)/2; ansy=(s[i].y+s[j].y)/2; bit=0; for(k=1;k<=n;k++) { if(k==i) {bit+=dir[i-1];continue;} if(k==j) {bit+=dir[j-1];continue;} if(dis(s[k].x,s[k].y,ansx,ansy)<=mid) bit+=dir[k-1]; } if(!hash[bit]) {hash[bit]=1;st[++sum]=bit;} } } } qsort(st+1,sum,sizeof(st[1]),cmp); for(i=sum;i>=1;i--) { for(j=1;j<=n;j++) if(st[i]&dir[j-1]) hash[st[i]-dir[j-1]]=0; if(hash[st[i]]==0) continue; r++; for(j=1;j<=n;j++) if(st[i]&dir[j-1]) {Link(r,j);hash[dir[j-1]]=0;} } if(Dance(0)) {ans=mid;right=mid-eps;} else left=mid+eps; } printf("%.6lf\n",ans); } return 0; }