洛谷P1742:最小圆覆盖,计算几何,贪心随机保证复杂度

正题

      最小圆覆盖是一个模板。

      在n个点中,构造一个尽量小的圆,使其覆盖所有的点。

      很明显,如果边上有一个点或者两个点,那么圆的大小可以再缩小。边上三个点的时候就刚刚好可以固定一个圆。

      那么我们很容易就可以打出一个n的三次方的模板,只要经过一定的优化就可以打出下面的模板。

#include
#include
#include
#include
#include
#include
using namespace std;

int n;
struct node{
	double x,y;
}s[100010],ci;
double r=0;

double dou(double x){
	return x*x;
}

double get_dis(node x,node y){
	return sqrt(dou(x.x-y.x)+dou(x.y-y.y));
}

int calc_c(double a,double b,double c,double d,double e,double f){
	ci.x=(e*d-b*f)/(a*d-b*c);
	ci.y=(e*c-a*f)/(b*c-a*d);
	return 1;
}

bool uninside(node x){
	return get_dis(ci,x)>r;
}

void get_ans(){
	ci.x=0,ci.y=0;r=0;
	for(int i=1;i<=n;i++){
		if(!uninside(s[i])) continue; 
		ci=s[i];
		r=0;
		for(int j=1;j

      里面那个长长的就是已知三个点,求圆的方程,不会的可以自己推一推,在这里不多说。

      看起来好像是n的三次方的复杂度,其实随机上来说,复杂度是接近n的。

      因为一个点不在 能覆盖前面的圆 几率只是3/i,因为第i个点在那之外,它只会替换那三个点中的任意一个点。而剩下的几率就是不替换,所以几率是3/i;

      那么倒数第二层的进入几率就是3/i,每次复杂度是j,所以一共3n,否则就是1的复杂度。

      加起来接近线性。

你可能感兴趣的:(洛谷P1742:最小圆覆盖,计算几何,贪心随机保证复杂度)