zoukankan      html  css  js  c++  java
  • 【JZOJ5094】【GDSOI2017第四轮模拟day3】鸽子 计算几何+floyd

    题面

    养鸽人要监视他的鸽子,有n只鸽子站在平面上,他可以在m个给定的点上设置监视器,如果一只鸽子在某个监视器上或者在两个监视器所连直线上或者在三个监视器所连直线的三角形内则其就咕咕咕了,现在养鸽人要让所有鸽子咕咕咕,请问他最少需要设置多少监视器。
    对于100%的数据n≤100000,m≤500,坐标绝对值不超过10的9次方。

    100

    首先转化一下题意,就是选取尽量少的点,然后生成一个凸包,包住给定的一个凸包。
    显然在给定凸包内的点是没有用处的。
    对于不在给定凸包内的点,我们枚举它们:
    对于一个点i,找出其与给定凸包的两条“切线”。

    如图,两条切线即为x,y,那么就有使(i)给图中蓝色的点连一条长度为1的边。
    由于凸包是,一个点出发,回到这个点的最短路。
    然后做一遍floyd就可以了。

    Code

    #include<bits/stdc++.h>
    #define ll long long
    #define db double
    #define fo(i,x,y) for(int i=x;i<=y;i++)
    #define fd(i,x,y) for(int i=x;i>=y;i--)
    using namespace std;
    const int inf=0x7fffffff;
    const char* fin="pigeon.in";
    const char* fout="pigeon.out";
    const int maxn=100007,maxm=507;
    const db eps=1e-10;
    int equ(db v,db c){return (fabs(v-c)<eps?0:(v<c?-1:1));}
    struct P{
    	db x,y;
    	P(db _x=0,db _y=0){x=_x;y=_y;}
    	P operator +(const P &b)const{return P(x+b.x,y+b.y);}
    	P operator -(const P &b)const{return P(x-b.x,y-b.y);}
    	db operator ^(const P &b)const{return x*b.y-b.x*y;}
    	db arg()const{return atan2(y,x);}
    	void ni(){x=-x;y=-y;}
    	void p(){printf("%lf %lf
    ",x,y);}
    }a[maxn],b[maxm],c[maxn];
    int n,m,N,f[maxm][maxm];
    void floyd(){
    	fo(k,1,m) fo(i,1,m) fo(j,1,m)
    		if (f[i][k]<2000000000 && f[k][j]<2000000000)
    			f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
    }
    int main(){
    	freopen(fin,"r",stdin);
    	freopen(fout,"w",stdout);
    	scanf("%d%d",&n,&m);
    	fo(i,1,n) scanf("%lf%lf",&a[i].x,&a[i].y);
    	fo(i,1,m) scanf("%lf%lf",&b[i].x,&b[i].y);
    	memset(f,127,sizeof f);
    	bool debug=false;
    	fo(i,1,m){
    		int mxid=0,mnid=0,lid=0,hid=0;
    		db low,high;
    		P mx,mn;
    		fo(j,1,n){
    			if (a[j].x==b[i].x && a[j].y==b[i].y) continue;
    			db x=(a[j]-b[i])^(a[1]-b[i]);
    			P tmp=(a[j]-b[i]);
    			if (mxid==0 || equ(mx^tmp,0)>0) mx=tmp,mxid=j;
    			if (mnid==0 || equ(mn^tmp,0)<0) mn=tmp,mnid=j;
    			if (hid==0 || high<x) high=x,hid=j;
    			if (lid==0 || low>x) low=x,lid=j;
    		}
    		if (equ((a[hid]-b[i])^(a[lid]-b[i]),0)<0) continue;
    		P da=mx,xiao=mn;
    		if (debug) xiao.p(),da.p();
    		da.ni();
    		fo(j,1,m)
    			if (i!=j){
    				P tmp=b[j]-b[i];
    				if (debug){
    					tmp.p();//printf(":%lf %lf
    ",xiao^tmp,tmp^da);
    					printf(":%d %d
    ",equ(xiao^tmp,0)<=0,equ(tmp^da,0)<=0);
    				}
    				if (equ(xiao^tmp,0)<=0 && equ(tmp^da,0)<=0) f[i][j]=1;
    			}
    		if (debug)printf("
    ");
    	}
    	floyd();
    	int ans=inf;
    	fo(i,1,m) ans=min(ans,f[i][i]);
    	if (ans<2000000000) printf("%d",ans);
    	else printf("-1");
    	return 0;
    }
    
  • 相关阅读:
    大数据集群环境ssh免密码登录设置
    FreeRTOS任务创建删除
    BLE外设设计
    BLE控制器之链路层
    BLE控制器之链路层二
    BLE控制器之物理层特性
    BLE基本理论和概念
    BLE主机之ATT和GATT
    BLE主机之SM层
    BLE主机之L2CAP层
  • 原文地址:https://www.cnblogs.com/hiweibolu/p/6774648.html
Copyright © 2011-2022 走看看