BZOJ 2458: [BeiJing2011]最小三角形(分治)

版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/88948340

题目
像平面最近点对那样分治,枚举点的时候大胆枚举,小心剪枝即可AC

AC Code:

#include<bits/stdc++.h>
#define maxn 200005
using namespace std;

int n;
int x[maxn],y[maxn],c[maxn];
double sqr(double a){ return a*a; }
double dist(int a,int b){ return sqrt(sqr(x[a]-x[b])+sqr(y[a]-y[b])); }
inline bool cmp1(const int &u,const int &v){ return x[u]<x[v]; }
//inline bool cmp2(const int &u,const int &v){ return y[u]<y[v]; }

double ans = 0x3f3f3f3f;
void Solve(int l,int r){
	if(l>=r) return;
	int mid = (l+r) >> 1;
	Solve(l,mid),Solve(mid+1,r);
	for(int i=l,j=mid+1;i<=mid;i++)
		//if(fabs(x[c[i]]-x[c[mid]])<ans)
		{
			for(;j<=r && y[c[i]]-y[c[j]]>=ans;j++);
			for(int v=j;v<=r && y[c[v]]-y[c[i]]<=ans;v++)
				if(fabs(x[c[v]]-x[c[i]])<ans)
				{
					for(int u=i+1;u<=mid&& 2*y[c[u]]-2*y[c[i]]<=ans;u++)
						ans = min(ans , dist(c[i],c[v])+dist(c[i],c[u])+dist(c[v],c[u]));
					for(int u=v+1;u<=r  && 2*y[c[u]]-2*y[c[i]]<=ans;u++)
						ans = min(ans , dist(c[i],c[v])+dist(c[i],c[u])+dist(c[v],c[u]));
				}
		}
	static int tmp[maxn];
	int i=l,j=mid+1,k=l;
	for(;i<=mid && j<=r;)
		if(y[c[i]] < y[c[j]]) tmp[k++]=c[i++];
		else tmp[k++]=c[j++];
	for(;i<=mid;) tmp[k++]=c[i++];
	for(;j<=r;) tmp[k++]=c[j++];
	for(i=l;i<=r;i++) c[i]=tmp[i];
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]),c[i]=i;
	sort(c+1,c+1+n,cmp1);
	Solve(1,n);
	printf("%.6lf\n",ans);
}

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/88948340