#include
int main()
{
puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢");
puts("网址:blog.csdn.net/vmurder/article/details/46605193");
}
首先最小圆覆盖虽然有三层 for 循环,但是它是期望 O(n) 的。什么?你问我为啥?那我只能呵呵了,50W的 O(n3) 高速跑过。
后交的是不求凸包直接跑的,先交的是求了凸包再跑的。。并没有什么差距。
这道题我们可以先写一份求凸包来缩减点的规模,如果点是随机生成的,那么期望有不到100个点在凸包上,然后就可以乱搞了(其实毛用没有2333)
然后这道题需要用到 [最小圆覆盖] (呃其实这道题就是裸的最小圆覆盖……)
初始圆为 点 1 这个半径为 0 的圆。。
for1ni=2 若 i 不在已有圆中,则求一个圆周包含 i 的最小圆。
{
圆改为点 i 这个半径为 0 的圆
for2i−1j=1 若 j 不在已有圆中,则求一个圆周包含 i、j 的最小圆。
{
圆改为以线段 (i,j) 为直径的圆
for2j−1k=1 若 k 不在已有圆中,则求一个圆周包含 i、j、k 的最小圆。
{
圆改为三角形 (i,j,k) 的外接圆
}
}
}
返回圆
真是奇葩。QwQ
那个求三角形外心不妨自己乱搞,这里的那个是懒得推直接扒的,然后没看懂QwQ
#include
#include
#include
#include
#define N 501000
#define eps 1e-7
using namespace std;
struct Point
{
double x,y;
Point(double _x=0,double _y=0):x(_x),y(_y){}
void read(){scanf("%lf%lf",&x,&y);}
bool operator < (const Point &A)const
{return fabs(x-A.x)double operator - (const Point &A)const
{return sqrt((x-A.x)*(x-A.x)+(y-A.y)*(y-A.y));}
void print(){printf("%.2lf %.2lf ",x,y);}
}p[N];
struct Circle
{
Point c; // center
double r;
Circle(Point _c=Point(0,0),double _r=0):c(_c),r(_r){}
bool operator ^ (const Point &A)const{return A-c>r+eps;} // 包含
void print()
{
c.print();
printf("%.2lf\n",r);
}
};
inline double xmul(const Point &A,const Point &B,const Point &C)
{return (C.y-A.y)*(B.x-A.x)-(B.y-A.y)*(C.x-A.x);}
struct Get_Convex_Hull
{//求凸包
int stk1[N],top1,stk2[N],top2;
Point tp[N];
void work(Point *p,int &n)
{
int i;
sort(p+1,p+n+1);
stk1[top1=1]=1;
for(i=2;i<=n;i++)
{
while(top1>1&&xmul(p[stk1[top1-1]],p[stk1[top1]],p[i])>-eps)top1--;
stk1[++top1]=i;
}
stk2[top2=1]=n;
for(i=n-1;i;i--)
{
while(top2>1&&xmul(p[stk2[top2-1]],p[stk2[top2]],p[i])>-eps)top2--;
stk2[++top2]=i;
}
n=0;
for(i=1;ifor(i=1;ifor(i=1;i<=n;i++)p[i]=tp[i];
}
}gch;
struct Get_Min_Circle_Cover
{
Point circumcenter(const Point &a,const Point &b,const Point &c)
{//返回三角形的外心 我并不知道这是什么鬼。。好强的样子。
Point ret;
double a1=b.x-a.x,b1=b.y-a.y,c1=(a1*a1+b1*b1)/2;
double a2=c.x-a.x,b2=c.y-a.y,c2=(a2*a2+b2*b2)/2;
double d=a1*b2-a2*b1;
ret.x=a.x+(c1*b2-c2*b1)/d;
ret.y=a.y+(a1*c2-a2*c1)/d;
return ret;
}
Circle work(int n)
{
random_shuffle(p+1,p+n+1);
Circle C=Circle(p[1],0);
int i,j,k;
for(i=2;i<=n;i++)if(C^p[i])
{
C=Circle(p[i],0);
for(j=1;jif(C^p[j])
{
C.c=Point((p[i].x+p[j].x)/2,(p[i].y+p[j].y)/2);
C.r=p[j]-C.c;
for(k=1;kif(C^p[k])//求外接圆圆心,要求三点不能共线
C.c=circumcenter(p[i],p[j],p[k]),C.r=C.c-p[i];
}
}
return C;
}
}gmcc;
int main()
{
// freopen("test.in","r",stdin);
int i=0,n;
scanf("%d",&n);
for(i=1;i<=n;i++)p[i].read();
// gch.work(p,n);
Circle ret=gmcc.work(n);
ret.print();
return 0;
}