最小圆覆盖简笔
作者:互联网
用最小的圆覆盖平面上的n个点,通常采用O(n)的随机增量法。
定理:如果点集S的最小覆盖圆覆盖不了P,那么{P∪S}的最小覆盖圆一定过P。
首先将n个点random_shuffle。
设当前的⚪是C,如果枚举到Pi在圆外,则限定Pi在圆上,从1 ~ i-1枚举j,如果枚举到Pj在圆外,则限定Pj在圆上,从1 ~ j-1枚举k,如果枚举到Pk在圆外,则用(Pi,Pj,Pk)的外接圆更新当前圆。看起来是三层循环,但是由于有随机化,可以证明复杂度是O(n)的。
Q Circle(P A,P B,P C){
double A1=2*(B.x-A.x),
B1=2*(B.y-A.y),
C1=sq(B.x)+sq(B.y)-sq(A.x)-sq(A.y),
A2=2*(C.x-B.x),
B2=2*(C.y-B.y),
C2=sq(C.x)+sq(C.y)-sq(B.x)-sq(B.y);
double a=sqrt(sq(B.x-C.x)+sq(B.y-C.y)),
b=sqrt(sq(A.x-C.x)+sq(A.y-C.y)),
c=sqrt(sq(A.x-B.x)+sq(A.y-B.y)),
p=(a+b+c)/2,
S=sqrt(p*(p-a)*(p-b)*(p-c));
return (Q){(P){(C1*B2-C2*B1)/(A1*B2-A2*B1),(A1*C2-A2*C1)/(A1*B2-A2*B1)},a*b*c/4/S};
}
Q Mcircle(int l,int r){
for(int i=l;i<=r;i++)a[i]=b[i];
random_shuffle(a+l,a+r+1);
Q Cir=Q{P{0.0,0.0},0.0};
for(int i=l;i<=r;i++)
if(dist(Cir.p,a[i])>Cir.r+1e-7){
Cir=Q{a[i],0};
for(int j=l;j<i;j++)
if(dist(Cir.p,a[j])>Cir.r+1e-7){
Cir=Q{P{(a[i].x+a[j].x)/2,(a[i].y+a[j].y)/2},dist(a[i],a[j])/2};
for(int k=l;k<j;k++)
if(dist(Cir.p,a[k])>Cir.r)
Cir=Circle(a[i],a[j],a[k]);
}
}
return Cir;
}
标签:覆盖,int,sq,最小,sqrt,A1,枚举,A2,简笔 来源: https://www.cnblogs.com/impyl/p/16368028.html