LGP4518[JSOI2018]绝地反击


题解:
- 只要确定了每艘飞船的就位位置,就可以用二分+网络流求得答案;
- 定义偏转角度$a$为离$x$正半轴逆时针最近的边的弧度,$a \in [0,\frac{2\pi}{n})$
- 二分一个值,对于一个点可以求出可到达的弧度记为$[l,r]$
- 那么在$[0,a]$的移动范围内只有可能前面一个点删除,后面一个点加入;
- 对$O(n)$个关键点做网络流即可;
- 复杂度$O(n^4 \ logn)$
- 如果将关键点排序,每次只考虑变化的边退流可以优化到:$O(n^3 \log n)$
#include<bits/stdc++.h>
#define ld double
using namespace std;
const int N=,M=,inf=0x3f3f3f3f;
const ld Pi=acos(-),eps=1e-;
int n,S,T,vis[N],hd[N],o,cur[N],d[N],que[N],head,tail,flow,cnt;
ld R,B;
struct Edge{int v,nt,f;}E[M<<];
struct poi{ld x,y;}p[N];
ld dis(poi A){return sqrt(A.x*A.x+A.y*A.y);}
struct data{
ld ang;int u,v,t;
data(ld _ang=,int _u=,int _v=,int _t=):ang(_ang),u(_u),v(_v),t(_t){};
bool operator <(const data&A)const{return ang==A.ang?t>A.t:ang<A.ang;}
}q[N];
bool bfs(){
for(int i=S;i<=T;++i)vis[i]=,cur[i]=hd[i];
head=tail=;vis[que[++tail]=S]=d[S]=;
while(head<tail){
int u=que[++head];
for(int i=hd[u];~i;i=E[i].nt)if(E[i].f){
int v=E[i].v;
if(vis[v])continue;
vis[v]=;d[v]=d[u]+;que[++tail]=v;
if(v==T)return true;
}
}
return false;
}
int dfs(int u,int c){
if(u==T||!c)return c;
int flow=,f;
for(int i=cur[u];~i;i=E[i].nt){
int v=E[cur[u]=i].v;
if(d[v]==d[u]+&&(f=dfs(v,min(E[i].f,c)))){
flow+=f;c-=f;
E[i].f-=f;E[i^].f+=f;
if(!c)break;
}
}
return flow;
}
void add(int u,int v){
E[o]=(Edge){v,hd[u],};hd[u]=o++;
E[o]=(Edge){u,hd[v],};hd[v]=o++;
}
void del(int u,int v){
int fg=;
for(int i=hd[u];~i;i=E[i].nt)if(E[i].v==v){
if(!E[i].f)flow--;else fg=;
E[i].f=E[i^].f=;
break;
}
if(fg)return;
for(int i=hd[S];~i;i=E[i].nt)if(E[i].v==u){
E[i].f=;E[i^].f=;break;
}
for(int i=hd[v];~i;i=E[i].nt)if(E[i].v==T){
E[i].f=;E[i^].f=;break;
}
if(bfs())flow+=dfs(S,inf);
}
bool check(ld mid){
flow=cnt=o=;
for(int i=S;i<=T;++i)hd[i]=-;
for(int i=;i<=n;++i){
ld d=dis(p[i]);
if(mid+d<=R||mid+R<=d)return false;
if(R+d<=mid){
for(int j=;j<=n;++j)add(i,j+n);
continue;
}
ld ang=atan2(p[i].y,p[i].x);
ld del=acos((d*d+R*R-mid*mid)/(*d*R));
ld ang1=ang-del,ang2=ang+del;
while(ang1<)ang1+=Pi*;
while(ang2<)ang2+=Pi*;
int l=ang1/B,r=ang2/B;
ang1=ang1-B*l;
ang2=ang2-B*r;
l++;r++;
q[++cnt]=(data){ang1,i,l,};
q[++cnt]=(data){ang2,i,r,-};
if(l<=r)for(int j=l+;j<=r;++j)add(i,j+n);
else {
for(int j=;j<=r;++j)add(i,j+n);
for(int j=l+;j<=n;++j)add(i,j+n);
}
}
sort(q+,q+cnt+);
for(int i=;i<=n;++i)add(S,i),add(i+n,T);
while(bfs())flow+=dfs(S,inf);
if(flow==n)return true;
for(int i=;i<=cnt;++i){
if(~q[i].t){
add(q[i].u,q[i].v+n);
if(bfs())flow+=dfs(S,inf);
if(flow==n)return true;
}
else del(q[i].u,q[i].v+n);
}
return false;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("P4518.in","r",stdin);
freopen("P4518.out","w",stdout);
#endif
scanf("%d%lf",&n,&R);
B=*Pi/n;S=,T=n*+;
for(int i=;i<=n;++i)scanf("%lf%lf",&p[i].x,&p[i].y);
ld l=,r=;
while(r-l>eps){
ld mid=(l+r)/;
if(check(mid))r=mid;
else l=mid;
}
printf("%.8lf\n",l+eps);
return ;
}
LGP4518[JSOI2018]绝地反击的更多相关文章
- 【BZOJ5316】[JSOI2018]绝地反击(网络流,计算几何,二分)
[BZOJ5316][JSOI2018]绝地反击(网络流,计算几何,二分) 题面 BZOJ 洛谷 题解 很明显需要二分一个答案. 那么每个点可以确定的范围就是以当前点为圆心,二分出来的答案为半径画一个 ...
- BZOJ5316 : [Jsoi2018]绝地反击
若$R=0$,那么显然答案为离原点最远的点到原点的距离. 否则若所有点都在原点,那么显然答案为$R$. 否则考虑二分答案$mid$,检查$mid$是否可行. 那么每个点根据对应圆交,可以覆盖圆上的一部 ...
- 洛谷P4518 [JSOI2018]绝地反击(计算几何+二分图+退流)
题面 传送门 题解 调了咱一个上午-- 首先考虑二分答案,那么每个点能够到达的范围是一个圆,这个圆与目标圆的交就是可行的区间,这个区间可以用极角来表示 首先,如果我们知道这个正\(n\)边形的转角,也 ...
- yyb省选前的一些计划
突然意识到有一些题目的计划,才可以减少大量查水表或者找题目的时间. 所以我决定这样子处理. 按照这个链接慢慢做. 当然不可能只做省选题了. 需要适时候夹杂一些其他的题目. 比如\(agc/arc/cf ...
- LOJ 2548 「JSOI2018」绝地反击 ——二分图匹配+网络流手动退流
题目:https://loj.ac/problem/2548 如果知道正多边形的顶点,就是二分答案.二分图匹配.于是写了个暴力枚举多边形顶点的,还很愚蠢地把第一个顶点枚举到 2*pi ,其实只要 \( ...
- 【LOJ】#2548. 「JSOI2018」绝地反击
题解 卡常卡不动,我自闭了,特判交上去过了 事实上90pts= = 我们考虑二分长度,每个点能覆盖圆的是一段圆弧 然后问能不能匹配出一个正多边形来 考虑抖动多边形,多边形的一个端点一定和圆弧重合 如果 ...
- 【JSOI2018】绝地反击
题面 50pts 首先当然是二分答案\(mid\), 对于每一个点,以它为圆心的圆,交上攻击轨道: 那么这个点到攻击轨迹的可达范围就是一段圆弧. 怎么求这段圆弧呢? 我们知道圆弧可以用其两端点对于圆心 ...
- JSOI2018简要题解
来自FallDream的博客,未经允许,请勿转载,谢谢. 有幸拜读到贵省的题目,题的质量还不错,而且相比zjoi可做多了,简单发一下题解吧. 还有就是,怎么markdown在博客园上的代码这么丑啊 「 ...
- JSOI2018 简要题解
潜入行动 复杂度分析题. 定义状态fi,j,0/1,0/1f_{i,j,0/1,0/1}fi,j,0/1,0/1表示以iii为根子树放jjj个机器iii这个放不放,iii这个是否已放来进行dpdpd ...
随机推荐
- python3使用csv包,读写csv文件
python操作csv,现在很多都用pandas包了,不过python还是有一个原始的包可以直接操作csv,或者excel的,下面举个例子说明csv读写csv文件的方法: import os impo ...
- Python中collections模块的使用
本文将详细讲解collections模块中的所有类,和每个类中的方法,从源码和性能的角度剖析. 一个模块主要用来干嘛,有哪些类可以使用,看__init__.py就知道 '''This module i ...
- Python图形界面开发—wxPython库的布局管理及页面切换
前言 wxPython是基于Python的跨平台GUI扩展库,对wxWidgets( C++ 编写)封装实现.GUI程序的开发中界面布局是很重要的一个部分,合理的页面布局能够给予用户良好使用体验.虽然 ...
- 互评Beta版本——杨老师粉丝群——Pinball
互评beta版本 杨老师粉丝群——<PinBall> 一.基于NABCD评论作品,及改进建议 1.根据(不限于)NABCD评论作品的选题 (1)N(Need,需求) 随着年龄的增长, ...
- 05慕课网《进击Node.js基础(一)》HTTP概念进阶(同步/异步)
HTTP模块介绍 支持http协议的更多特性 不缓存请求和响应 API比较底层处理流相关,信息解析 HTTP相关概念 回调 将函数作为参数传到执行函数中,参数函数在执行函数中嵌套执行 function ...
- 【每日scrum】第一次冲刺day2
和小伙伴一起找地图 ,学习了mapinfo地图格式的基本知识,数据和图像分开存储
- c#窗体移动与窗体阴影效果
//步骤//1.导入代码//2.事件中添加form_1mousedown函数//3.在load函数中定义AnimateWindow语句,注意有两个引用.//4.DllImport若有错误,按shift ...
- HDU 4568 Hunter 最短路+TSP
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4568 Hunter Time Limit: 2000/1000 MS (Java/Others)Me ...
- Virtualbox+Ubuntu安装,VERR_VMX_MSR_ALL_VMX_DISABLED解决
学习链接:基于VirtualBox虚拟机安装Ubuntu图文教程--娄老师 启动虚拟机遇到的问题:BIOS中VT-x在所有CPU模式下被禁用(VERR_VMX_MSR_ALL_VMX_DISABLED ...
- Alpha版本冲刺(二)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内 ...