省选专练JSOI2007合金

这个是真的想不到啊

第一你搞三维的没意义

于是乎,把c看做1-a-b那么c就没有了意义,因为确定了a,b辣么c自然确定下来

其次对于这个东西有着重要的引理:

对于二元笛卡尔基上的点(Ax,Ay)(Bx,By)他们的连线就是可以配凑的情况

辣么扩展到多个点进行配凑:由于可把这个线段上的每一个点都看做一种新点,于是这些点的连线可以扩展

呜呼,线的无限重叠就是面了啊!!!

顾:这实际是求多少个点构成的凸包可以包含一个点集

那么我们只要保证两个点的连线的左边或在线段上全是包含点集,那么这条边可以作为凸包的一条边

那么问题的本质是求最小环!!!

floyd就好了(或者说floyd本质是判断有无环但对于此题,只要你不做倍增限制边数那么环就是最小的)

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=501;
const double eps=1e-12;
const double INF=1e12;
int cmp(double A){
	if(fabs(A)<eps)return 0;
	else return(A>0)?1:-1;
}
struct Point{
	double x,y,z;
	Point(double _x=0.0,double _y=0.0):x(_x),y(_y){}
	friend Point operator + (Point A,Point B){return Point(A.x+B.x,A.y+B.y);}
	friend Point operator - (Point A,Point B){return Point(A.x-B.x,A.y-B.y);}
	friend Point operator * (Point A,double k){return Point(A.x*k,A.y*k);}
	friend Point operator / (Point A,double k){return Point(A.x/k,A.y/k);}
	void read(){scanf("%lf%lf%lf",&x,&y,&z);}
}A[N],B[N];
typedef Point Vector;
double Dot(Vector A,Vector B){
	return A.x*B.x+A.y*B.y;
}
double Cross(Vector A,Vector B){
	return A.x*B.y-A.y*B.x;
}
int m,n;
int mmp[N][N]={};
int main(){
	memset(mmp,0x3f,sizeof(mmp));
	scanf("%d%d",&m,&n);
	for(int i=1;i<=m;i++){
		A[i].read();
	}
	for(int i=1;i<=n;i++){
		B[i].read();
	}
	for(int i=1;i<=m;i++){
		for(int j=1;j<=m;j++){
			int flag=1;
			for(int k=1;k<=n;k++){
				Vector Vec1=A[i]-B[k];
				Vector Vec2=A[j]-B[k];
				if(cmp(Cross(Vec1,Vec2))>0){
					flag=0;
					break;
				}
				if(cmp(Cross(Vec1,Vec2)==0)&&!((B[k].x<=max(A[i].x,A[j].x))&&(B[k].x>=min(A[i].x,A[j].x))&&(B[k].y<=max(A[i].y,A[j].y))&&(B[k].y>=min(A[i].y,A[j].y)))){
					flag=0;
					break;
				}
			}
			if(flag==1){
//				cout<<i<<" "<<j<<'\n';
				mmp[i][j]=1;
			}
		}
	}
	int ans=501;
	for(int k=1;k<=m;k++){
		for(int i=1;i<=m;i++){
			for(int j=1;j<=m;j++){
				mmp[i][j]=min(mmp[i][k]+mmp[k][j],mmp[i][j]);
			}
		}
	}
	for(int i=1;i<=m;i++){
		ans=min(ans,mmp[i][i]);
	}
	if(ans!=501)
	cout<<ans;
	else cout<<-1;
} 


猜你喜欢

转载自blog.csdn.net/fcb_x/article/details/80465017