题面

养鸽人要监视他的鸽子,有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\n",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\n",xiao^tmp,tmp^da);
printf(":%d %d\n",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("\n");
}
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;
}

【JZOJ5094】【GDSOI2017第四轮模拟day3】鸽子 计算几何+floyd的更多相关文章

  1. 【JZOJ5093】【GDSOI2017第四轮模拟day3】字符串匹配 哈希

    题面 对于一个字符集大小为C的字符串P,我们可以将任意两种字符在P中的位置进行互换,例如P=abcba,我们交换a,b就变为bacab,交换a,d就变为dbcbd,交换可以进行任意次.若交换后P变为了 ...

  2. [第一波模拟\day3\T3]{益智游戏}(game.cpp)

    [问题描述] 小P和小R在玩一款益智游戏.游戏在一个正权有向图上进行. 小P控制的角色要从A点走最短路到B点,小R控制的角色要从C点走最短路到D点. 一个玩家每回合可以有两种选择,移动到一个相邻节点或 ...

  3. [第一波模拟\day3\T2]{独立集}(bubble.cpp)

    [问题描述] 有一天,一个名叫顺旺基的程序员从石头里诞生了.又有一天,他学会了冒泡排序和独立集.在一个图里,独立集就是一个点集,满足任意两个点之间没有边.于是他就想把这两个东西结合在一起.众所周知,独 ...

  4. HNOI模拟 Day3.25 By Yqc

    怕老婆 [问题描述] 有一天hzy9819,来到了一座大城市拥有了属于他自己的一双滑板鞋.但是他还是不满足想要拥有属于自己的一栋楼,他来到了一条宽敞的大道上,一个一个记录着这些楼的层数以方便自己选择. ...

  5. HNOI模拟 Day3.23

    一.拓扑(top)[ 题目描述]:给你一个有向二分图,求他的拓扑序列的个数.[ 输入]:第一行两个数 N,M,表示点数和边数.接下来 M 行每行两个数 a,b,表示 a 向 b 有一条有向边.[ 输出 ...

  6. HNOI模拟 Day3.22

    第一题: 盾盾的打字机 (drdrd) [题目描述] 盾盾有一个非常有意思的打字机,现在盾哥要用这台打字机来打出一段文章. 由于有了上次的经验,盾盾预先准备好了一段模板 A 存在了内存中,并以此为基础 ...

  7. 【JZOJ5088】【GDOI2017第四轮模拟day2】最小边权和 排序+动态规划

    题面 有一张n个点m条边的有向图,每条边有一个互不相同的边权w,有q个询问,要求你从点a经过不超过c条边到点b,要求经过的边权递增并和尽量小,求出最小的边权和,如果没有合法方案则输出-1. 对于100 ...

  8. 【JZOJ5086】【GDOI2017第四轮模拟day1】数列 折半搜索

    题面 有一个长度为n 的排列,现在有一些位置的数已经模糊不清了,你只知道这个排列的逆序对个数是K,你能计算出总共有多少可能的排列吗? 对于100% 的数据,n <=10^3,K<=10^9 ...

  9. 【JZOJ5081】【GDSOI2017第三轮模拟】Travel Plan 背包问题+双指针+树的dfs序

    题面 100 注意到ban的只会是一个子树,所以我们把原树转化为dfs序列. 然后题目就转化为,询问一段ban的区间,之后的背包问题. 比赛的时候,我想到这里,于是就开始想区间合并,于是搞了线段树合并 ...

随机推荐

  1. java基础之DateFormat类

    DateFormat DateFormat类概述 DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间. 是抽象类,所以使用其子类SimpleDateFor ...

  2. C++【string】用法和例子

    /*** * string 基础api复习 * 8 AUG 2018 */ #include <iostream> #include <string> using namesp ...

  3. [Bzoj3696]化合物【暴力+树形Dp】

    Online Judge:Bzoj3696 Label:暴力,树形Dp 题目描述 首长NOI惨跪,于是去念文化课了.现在,他面对一道化学题. 这题的来源是因为在一个奇怪的学校两个化竞党在玩一个奇怪的博 ...

  4. 去掉IE提示:在此页上的ActiveX控件和本页上的其他部分的交互可能不安全。你想允许这种交互吗?

    由于项目需求,需要用到OCX控件.而在IE浏览器中加载OCX控件会有如下提示: 这是因为OCX控件有一个ID,而这个ID注册后IE不认为该OCX控件是安全的.所以,必须把这个控件注册为安全控件. 假设 ...

  5. wpf listbox touch 整个窗口移动

    工作中遇到遇到,在有listbox中的地方,touch listbox的时候  可以把整个窗体都移动了,解决方案如下: /// <summary> /// prevent the rubb ...

  6. AppServer获取参数的方法

    AppServer中从APP_PARAM表中根据param_code获取param_value: appManageService.getParamValueByCode(param_code) -- ...

  7. extern “C”的用法

    引言 由于不同的代码互相调用起来很容易出错,甚至同一种代码但由不同的编译器编译,为实现C++代码调用其他C语言代码,会在C语言代码的部分加上extern "C",表明这段代码需要按 ...

  8. k8s 内部各个部件运转

    Master节点部署的都是kubernetes的核心模块APIServer提供资源操作的唯一入口,并且提供认证/授权/kubernets的访问控制可以通过kubectl和自己开发的客户端,通过http ...

  9. JAVA_环境配置

    1:系统环境 windows10 64位 jdk版本:jdk-8u131-windows-x64.exe,下载地址:http://www.oracle.com/technetwork/java/jav ...

  10. MATLAB---dir函数

    dir函数是最常用的转换路径的函数,可以获得指定文件夹下的所有子文件夹和文件,并存放在一个文件结构的数组中,这个数组各结构体内容如下: name    -- 文件名 date    -- 修改日期 b ...