题解
期望复杂度 O(n)
代码
//随机增量法求最小圆覆盖
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#define maxn 1000010
#define eps 1e-8
using namespace std;
typedef double real;
int N;
real r;
struct point
{
real x, y;
point(real x, real y):x(x),y(y){}
point(){};
}pt[maxn], _, o;
struct vec
{
point pt; real x, y;
vec(point pt, real x, real y):pt(pt),x(x),y(y){}
vec(){}
};
point operator+(point pt, vec v){return point(pt.x+v.x,pt.y+v.y);}
vec operator-(point p1, point p2){return vec(p2,p1.x-p2.x,p1.y-p2.y);}
vec operator+(vec v1, vec v2){return vec(_,v1.x+v2.x,v1.y+v2.y);}
vec operator-(vec v1, vec v2){return vec(_,v1.x-v2.x,v1.y-v2.y);}
vec operator*(vec v, real t){return vec(v.pt,v.x*t,v.y*t);}
vec operator/(vec v, real t){return vec(v.pt,v.x/t,v.y/t);}
real operator*(vec v1, vec v2){return v1.x*v2.y-v2.x*v1.y;}
point inter(vec v1, vec v2)
{
vec u=v1.pt-v2.pt; double t=v2*u/(v1*v2);
return v1.pt+v1*t;
}
point cen(point p1, point p2){return point((p1.x+p2.x)/2,(p1.y+p2.y)/2);}
point cen(point p1, point p2, point p3)
{
vec a=p2-p1, b=p3-p1;
a=vec(cen(p1,p2),-a.y,a.x), b=vec(cen(p1,p3),-b.y,b.x);
return inter(a,b);
}
double sqr(double x){return x*x;}
double dist(point p1, point p2){return sqrt(sqr(p2.x-p1.x)+sqr(p2.y-p1.y));}
void work()
{
int i, j, k;
random_shuffle(pt+1,pt+N+1);
o=pt[1];
for(i=2;i<=N;i++)
{
if(dist(o,pt[i])<r+eps)continue;
o=cen(pt[1],pt[i]), r=dist(o,pt[i]);
for(j=1;j<i;j++)
{
if(dist(o,pt[j])<r+eps)continue;
o=cen(pt[i],pt[j]), r=dist(o,pt[i]);
for(k=1;k<j;k++)
{
if(dist(o,pt[k])<r+eps)continue;
o=cen(pt[i],pt[j],pt[k]), r=dist(o,pt[i]);
}
}
}
}
int main()
{
int i;
scanf("%d",&N);
for(i=1;i<=N;i++)scanf("%lf%lf",&pt[i].x,&pt[i].y);
work();
printf("%.2lf %.2lf %.2lf",o.x,o.y,r);
return 0;
}