BZOJ3199 SDOI2013 逃考 半平面交、最短路
如果我们对于每一个点能找到与其相邻的点(即不经过其他点监视范围能够直接到达其监视范围的点)和是否直接到达边界,就可以直接BFS求最短路求出答案。
所以当前最重要的问题是如何找到对于每一个点相邻的点。
如果你知道泰森多边形,你就可以发现所有点的监视范围刚好对应这些点在这个矩形里的泰森多边形。
因为两个点监视范围的分界线一定在这两个点对应线段的中垂线上,所以将当前点到所有点的中垂线拿出来跑一遍半平面交,如果某个点与当前点的中垂线在半平面交中,那么这两个点就相邻。
还需要知道对于某个点能否不经过其他点的监视范围到达边界,这只需要在求半平面交的时候将矩形的四边也加上就可以了。
时间复杂度\(O(TN^2logN)\),可能需要轻微的常数优化。
写计算几何的时候务必注意细节,否则可能因为把\(xy\)坐标打反等小错误调很久QAQ
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
//This code is written by Itst
using namespace std;
#define ld long double
const ld eps = 1e-12;
bool cmp(ld a , ld b){return a - eps < b && a + eps > b;}
struct comp{
ld x , y , dir;
comp(ld _x = 0 , ld _y = 0) : x(_x) , y(_y){dir = atan2(y , x);}
comp operator +(comp a){return comp(x + a.x , y + a.y);}
comp operator -(comp a){return comp(x - a.x , y - a.y);}
comp operator *(ld a){return comp(x * a , y * a);}
ld operator *(comp a){return x * a.x + y * a.y;}
ld operator %(comp a){return x * a.y - y * a.x;}
bool operator <(const comp a)const{return dir < a.dir;}
bool operator ==(const comp a)const{return cmp(dir , a.dir);}
}now[607];
struct line{
comp pos , dir;
int ind;
line(comp a = comp(0,0) , comp b = comp(0,0) , int id = 0) : pos(a) , dir(b) , ind(id){}
bool operator <(const line a)const{return dir < a.dir || dir == a.dir && ((comp)a.pos - pos) % dir > 0;}
}cur[607];
struct Edge{
int end , upEd;
}Ed[370007];
int head[607] , que[607];
int cntEd , N , X0 , Y0 , X1 , Y1 , hd , tl , T;
bool mrk[607] , vis[607];
inline void addEd(int a , int b){
Ed[++cntEd] = (Edge){b , head[a]};
head[a] = cntEd;
}
comp rot(comp a){
ld Cos = 0 , Sin = 1;
return comp(a.x * Cos - a.y * Sin , a.x * Sin + a.y * Cos);
}
comp intersect(line a , line b){
ld t = (b.dir % (a.pos - b.pos)) / (a.dir % b.dir);
return a.pos + a.dir * t;
}
bool chk(line a , line b , line c){
return (intersect(a , b) - c.pos) % c.dir > 0;
}
void create(int x){
int cnt = 0;
cur[++cnt] = line(comp(0 , 0) , comp(1 , 0));
cur[++cnt] = line(comp(X1 , 0) , comp(0 , 1));
cur[++cnt] = line(comp(X1 , Y1) , comp(-1 , 0));
cur[++cnt] = line(comp(0 , Y1) , comp(0 , -1));
for(int i = 1 ; i <= N ; ++i)
if(i != x)
cur[++cnt] = line((now[i] + now[x]) * 0.5 , rot(now[i] - now[x]) , i);
sort(cur + 1 , cur + cnt + 1);
hd = tl = que[1] = 1;
for(int i = 2 ; i <= cnt ; ++i){
if(cur[i].dir == cur[i - 1].dir) continue;
while(hd < tl && chk(cur[que[tl]] , cur[que[tl - 1]] , cur[i]))
--tl;
while(hd < tl && chk(cur[que[hd]] , cur[que[hd + 1]] , cur[i]))
++hd;
que[++tl] = i;
}
while(hd < tl && chk(cur[que[tl]] , cur[que[tl - 1]] , cur[que[hd]]))
--tl;
while(hd <= tl){
if(!cur[que[hd]].ind) mrk[x] = 1;
else addEd(cur[que[hd]].ind , x);
++hd;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
ios::sync_with_stdio(0);
for(cin >> T ; T ; --T){
cntEd = 0;
memset(mrk , 0 , sizeof(mrk));
memset(vis , 0 , sizeof(vis));
memset(head , 0 , sizeof(head));
cin >> N >> X1 >> Y1 >> X0 >> Y0;
if(!N){cout << "0\n"; continue;}
for(int i = 1 ; i <= N ; ++i)
cin >> now[i].x >> now[i].y;
for(int i = 1 ; i <= N ; ++i)
create(i);
queue < int > q;
ld minDis = 1e18;
int minInd = 0;
for(int i = 1 ; i <= N ; ++i){
ld dis = sqrt((now[i].x - X0) * (now[i].x - X0) + (now[i].y - Y0) * (now[i].y - Y0));
if(dis < minDis){minDis = dis; minInd = i;}
}
vis[minInd] = 1;
q.push(minInd);
bool f = 0;
for(int i = 1 ; !f ; ++i){
for(int j = q.size() ; !f && j ; --j){
int t = q.front(); q.pop();
if(mrk[t]){f = 1; continue;}
for(int i = head[t] ; i ; i = Ed[i].upEd)
if(!vis[Ed[i].end]){
vis[Ed[i].end] = 1;
q.push(Ed[i].end);
}
}
if(f) cout << i << endl;
}
}
return 0;
}
BZOJ3199 SDOI2013 逃考 半平面交、最短路的更多相关文章
- [BZOJ3199][SDOI2013]escape:半平面交
分析 好像叫V图什么的. 容易发现,对于每个点,其监视的范围就是这个点与其它所有点的垂直平分线分割平面后的半平面交.由于数据范围很小,所以我们可以直接枚举每个点,使用双端队列求出其监视的范围.若两个点 ...
- Luogu3297 SDOI2013逃考(半平面交+最短路)
把每个人的监视范围看成点,相邻的两个监视范围连边,那么跑一遍最短路就可以了(事实上边权都为1可以直接bfs).显然存在最优路线没有某个时刻同时被多于两人监视,要到达另一个区域的话完全可以经过分界线而不 ...
- 洛谷 P3297 [SDOI2013]逃考 解题报告
P3297 [SDOI2013]逃考 题意 给一个平面矩形,里面有一些有标号点,有一个是人物点,人物点会被最近的其他点控制,人物点要走出矩形,求人物点最少被几个点控制过. 保证一开始只被一个点控制,没 ...
- 【BZOJ-4515】游戏 李超线段树 + 树链剖分 + 半平面交
4515: [Sdoi2016]游戏 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 304 Solved: 129[Submit][Status][ ...
- poj3335 半平面交
题意:给出一多边形.判断多边形是否存在一点,使得多边形边界上的所有点都能看见该点. sol:在纸上随手画画就可以找出规律:按逆时针顺序连接所有点.然后找出这些line的半平面交. 题中给出的点已经按顺 ...
- POJ3525 半平面交
题意:求某凸多边形内部离边界最远的点到边界的距离 首先介绍半平面.半平面交的概念: 半平面:对于一条有向直线,它的方向的左手侧就是它所划定的半平面范围.如图所示: 半平面交:多个半平面的交集.有点类似 ...
- POJ 3130 How I Mathematician Wonder What You Are! /POJ 3335 Rotating Scoreboard 初涉半平面交
题意:逆时针给出N个点,求这个多边形是否有核. 思路:半平面交求多边形是否有核.模板题. 定义: 多边形核:多边形的核可以只是一个点,一条直线,但大多数情况下是一个区域(如果是一个区域则必为 ).核内 ...
- bzoj2618[Cqoi2006]凸多边形 半平面交
这是一道半平面交的裸题,第一次写半平面交,就说一说我对半平面交的理解吧. 所谓半平面交,就是求一大堆二元一次不等式的交集,而每个二元一次不等式的解集都可以看成是在一条直线的上方或下方,联系直线的标准方 ...
- POJ 3384 Feng Shui 半平面交
题目大意:一个人很信"Feng Shui",他要在房间里放两个圆形的地毯. 这两个地毯之间可以重叠,可是不能折叠,也不能伸到房间的外面.求这两个地毯可以覆盖的最大范围.并输出这两个 ...
随机推荐
- 轻量简单好用的C++JSON库CJsonObject
1. JSON概述 JSON: JavaScript 对象表示法( JavaScript Object Notation) .是一种轻量级的数据交换格式. 它基于ECMAScript的一个子集.许多编 ...
- python 饥饿的小易(网易笔试题)
本周早些时候,学弟给我发了一道网易的笔试题,饥饿的小易,感觉有点意思-分享给大家 题目描述: 小易总是感觉饥饿,所以作为章鱼的小易经常出去寻找贝壳吃.最开始小易在一个初始位置x_0.对于小易所处的当前 ...
- Linux如何查看YUM的安装目录
Linux下如何查看使用YUM安装过的包的安装路径呢? 在搞清楚这个问题前,我们先来了解一下YUM. YUM(全称为 Yellow dog Updater, Modified)是一个在Fedora和R ...
- Reporting Service 2008 “报表服务器数据库内出错。此错误可能是因连接失败、超时或数据库中磁盘空间不足而导致的”
今天遇到了两个关于Reporting Service的问题, 出现问题的环境为Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64) .具体情况 ...
- JavaWeb入门笔记
Java web笔记 一.HTTP协议 HTTP(超文本传输协议),它是一种主流B/S架构中应用的通信协议.具有以下特点: 1.无状态 服务端不会记录客户端每次提交的请求,服务器一旦相应客户端之后,就 ...
- Ubuntu 12.04上安装Hadoop并运行
Ubuntu 12.04上安装Hadoop并运行 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 在官网上下载好四个文件 在Ubuntu的/home/w ...
- java操作elasticsearch实现查询删除和查询所有
后期博客本人都只给出代码,具体的说明在代码中也有注释. 1.查询删除 //查询删除:将查询到的数据进行删除 @Test public void test8() throws UnknownHostEx ...
- Beta阶段 - 博客链接合集
Beta阶段 - 博客链接合集 项目Github地址 安卓端(Stardust):https://github.com/StardustProject/Stardust 服务器端(Gravel):ht ...
- Hadoop下添加节点和删除节点
添加节点 1.修改host 和普通的datanode一样.添加namenode的ip 2.修改namenode的配置文件conf/slaves 添加新增节点的ip或host 3.在新节点的机器 ...
- (转)Spring Boot(五):Spring Boot Jpa 的使用
http://www.ityouknow.com/springboot/2016/08/20/spring-boot-jpa.html 在上篇文章Spring Boot(二):Web 综合开发中简单介 ...