bzoj 1337 最小圆覆盖
- 补充一个求三角形外心的向量法.用了点积的几何意义,很实用.出处.
- 使用随机增量法求.首先随机打乱顺序,然后三重循环,选择当前在圆外的点更新圆,分别按照 \(1/2/3\) 个点确定圆的方式更新即可.
- 由于随机一个点不在前 \(i\) 个点的最小覆盖圆内的概率是 \(\frac 3 i\) ,可以证明这样的时间复杂度是 \(O(n)\) 的,这种做法可以推广到常数维度上,时间复杂度仍为 \(O(n)\) .
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
inline int read()
{
int x=0;
bool pos=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar())
if(ch=='-')
pos=0;
for(;isdigit(ch);ch=getchar())
x=x*10+ch-'0';
return pos?x:-x;
}
const double eps=1e-9;
const int MAXN=1e5+10;
int dcmp(double x)
{
return fabs(x)<=eps?0:(x>0?1:-1);
}
struct v2{
double x,y;
v2(double x=0,double y=0):x(x),y(y) {}
v2 operator + (const v2 &rhs) const
{
return v2(x+rhs.x,y+rhs.y);
}
v2 operator / (const double &rhs) const
{
return v2(x/rhs,y/rhs);
}
v2 operator - (const v2 &rhs) const
{
return v2(x-rhs.x,y-rhs.y);
}
double operator * (const v2 &rhs) const
{
return x*rhs.y-y*rhs.x;
}
double modulus()
{
return sqrt(x*x+y*y);
}
};
double dist(v2 a,v2 b)
{
return (a-b).modulus();
}
v2 CirCentre(v2 a,v2 b,v2 c)
{
v2 centre;
double a1=b.x-a.x;
double b1=b.y-a.y;
double c1=(a1*a1+b1*b1)/2.0;
double a2=c.x-a.x;
double b2=c.y-a.y;
double c2=(a2*a2+b2*b2)/2.0;
double d=a1*b2-a2*b1;
centre.x=a.x+(c1*b2-c2*b1)/d;
centre.y=a.y+(a1*c2-a2*c1)/d;
return centre;
}
bool incircle(v2 p,v2 centre,double r)
{
return dcmp(dist(p,centre)-r)<=0;
}
void MinCircleCover(v2 *p,int n,v2 ¢re,double &r)
{
srand(time(NULL));
random_shuffle(p+1,p+1+n);
centre=p[1];
r=0;
for(int i=2;i<=n;++i)
{
if(!incircle(p[i],centre,r))
{
centre=p[i];
r=0;
for(int j=1;j<i;++j)
{
if(!incircle(p[j],centre,r))
{
centre=(p[i]+p[j])/2.0;
r=(p[i]-p[j]).modulus()/2.0;
for(int k=1;k<j;++k)
{
if(!incircle(p[k],centre,r))
{
centre=CirCentre(p[i],p[j],p[k]);
r=dist(centre,p[i]);
}
}
}
}
}
}
}
int n;
v2 p[MAXN];
int main()
{
n=read();
for(int i=1;i<=n;++i)
scanf("%lf%lf",&p[i].x,&p[i].y);
v2 centre;
double r;
MinCircleCover(p,n,centre,r);
printf("%.3lf\n",r);
return 0;
}
原文地址:https://www.cnblogs.com/jklover/p/10388841.html
时间: 2024-10-12 11:20:43