[JZOJ5094]鸽子
来源:互联网 发布:怎样退出淘宝账号 编辑:程序博客网 时间:2024/06/10 04:38
题目大意
给定平面上的
你要从
输出最少要选的待选点数,无解输出
题目分析
显然,我选择一些待选点,它们能观察到到的区域就是它们的凸包。
那么我现在相当于要选择尽量少的点,使得它们的凸包包含了所有关键点。
利用凸的定义进一步转化:选择尽量少的点,使得它们的凸包包含了关键点的凸包。
这个怎么求呢?考虑两个待选点之间的有向边,如果凸包在这条有向边的逆时针方向,我就连这条边。那么最后我对这个图求一个长度最小的简单环就是答案了。这个可以使用
现在考虑怎么连边,枚举两个待选点然后在凸包上判断好像不太可做。那么考虑枚举一个待选点,然后
时间复杂度
代码实现
#include <algorithm>#include <iostream>#include <cstdio>#include <cfloat>#include <cctype>#include <cmath>using namespace std;int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar(); while (isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f;}typedef long long db;const int N=100050;const int M=505;struct P{ db x,y; P(db x_=0.,db y_=0.){x=x_,y=y_;} P operator+(P const p)const{return P(x+p.x,y+p.y);} P operator-(P const p)const{return P(x-p.x,y-p.y);} P operator*(db const k)const{return P(x*k,y*k);} db operator^(P const p)const{return x*p.y-y*p.x;}}mon[M],pts[N];struct poly{ P p[N]; int tot; bool inside(P pts) { bool ret=0; for (int i=1;i<tot;++i) ret^=(p[i].y-pts.y>=0&&p[i+1].y-pts.y<0)||(p[i].y-pts.y<0&&p[i+1].y-pts.y>=0); return ret; }}ch;bool cmp1(int x,int y){return pts[y].x-pts[x].x>0||pts[x].x==pts[y].x&&pts[y].y-pts[x].y>0;}bool cmp2(int x,int y){return pts[x].x-pts[y].x>0||pts[x].x==pts[y].x&&pts[x].y-pts[y].y>0;}int kth[N],stack[N];bool able[M][M];int f[M][M];int n,m,ans,top;void update(int &x,int y){x=x<y?x:y;}void Convex_Hull(){ for (int i=1;i<=n;++i) kth[i]=i; sort(kth+1,kth+1+n,cmp1); top=0; for (int i=1;i<=n;++i) { P p=pts[kth[i]]; for (;top>1&&((pts[stack[top]]-pts[stack[top-1]])^(p-pts[stack[top-1]]))<=0;--top); stack[++top]=kth[i]; } for (int i=1;i<=top;++i) ch.p[++ch.tot]=pts[stack[i]]; for (int i=1;i<=n;++i) kth[i]=i; sort(kth+1,kth+1+n,cmp2); top=0; for (int i=1;i<=n;++i) { P p=pts[kth[i]]; for (;top>1&&((pts[stack[top]]-pts[stack[top-1]])^(p-pts[stack[top-1]]))<=0;--top); stack[++top]=kth[i]; } for (int i=2;i<=top;++i) ch.p[++ch.tot]=pts[stack[i]];}void pre(){ for (int i=1;i<=m;++i) { if (ch.inside(mon[i])) continue; P v1=ch.p[1]-mon[i],v2=ch.p[1]-mon[i]; for (int j=2;j<=ch.tot;++j) { P v=ch.p[j]-mon[i]; if (!v.x&&!v.y) continue; if (!v1.x&&!v1.y||(v^v1)>0) v1=v; if (!v2.x&&!v2.y||(v2^v)>0) v2=v; } v2=v2*(-1.0); for (int j=1;j<=m;++j) { P v=mon[j]-mon[i]; if (i!=j) able[i][j]=(v^v1)>=0&&(v2^v)>=0; } }}void dp(){ for (int i=1;i<=m;++i) for (int j=1;j<=m;++j) f[i][j]=m*2; for (int i=1;i<=m;++i) for (int j=1;j<=m;++j) if (able[i][j]) f[i][j]=1; for (int k=1;k<=m;++k) for (int i=1;i<=m;++i) for (int j=1;j<=m;++j) update(f[i][j],f[i][k]+f[k][j]); ans=m*2; for (int i=1;i<=m;++i) update(ans,f[i][i]); if (ans==m*2) ans=-1;}int main(){ freopen("pigeon.in","r",stdin),freopen("pigeon.out","w",stdout); n=read(),m=read(); for (int i=1,x,y;i<=n;++i) x=read(),y=read(),pts[i]=P(x,y); Convex_Hull(); for (int i=1,x,y;i<=m;++i) x=read(),y=read(),mon[i]=P(x,y); pre(),dp(),printf("%d\n",ans); fclose(stdin),fclose(stdout); return 0;}
0 0
- [JZOJ5094]鸽子
- 【jzoj5094】【GDSOI2017第四轮模拟day3】【鸽子】【计算几何】
- 鸽子用法
- 鸽子情缘
- 鸽子兔子
- 亲手清除鸽子
- 女生与鸽子
- 网络“鸽子”病毒猖獗
- 口渴的鸽子
- 蚂蚁与鸽子
- 兔子和鸽子
- 鸽子集结哨
- 生物导航-鸽子
- 鸽子浏览器(序)-鸽子浏览器的由来
- 河北省博物馆广场的鸽子
- 项目被放了鸽子
- 黑防鸽子完美的菜鸟级免杀
- 从鸽子搬家看认清自己
- BZOJ1927: [Sdoi2010]星际竞速
- JavaScript学习笔记5-变量和字符串的使用
- dpdk 网卡统计问题
- The Tomcat installation directory is not valid. It is missing...
- Cefsharp.Wpf 打包
- [JZOJ5094]鸽子
- 64位jdk编译的项目 在32位jdk上运行不正常!
- 漏洞库网站
- bzoj 4765: 普通计算姬 分块
- opencv 判断矩阵相等
- 1095: [ZJOI2007]Hide 捉迷藏
- Android 置Activity全屏和无标题
- vsftpd服务
- wechall php系列之No Escape