P3297 [SDOI2013]逃考
完全看不出这思路是怎么来的……
首先对于两个亲戚,他们监视范围的边界是他们连线的中垂线。那么对于一个亲戚来说它能监视的范围就是所有的中垂线形成的半平面交
然后如果某两个亲戚的监视范围有公共边,那么就在这两个亲戚之间连一条边,如果某个亲戚的监视范围和矩阵边界有公共边,那么就把这个亲戚和终点连边。然后以一开始监视的亲戚为起点,跑一遍最短路即可
//minamoto
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define fp(i,a,b) for(register int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i)
#define go(u) for(register int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
using namespace std;
int read(){
int res,f=1;char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=10005;
int S,T,n,times,sx,sy,bx,by,no[N],m;
struct Graph{
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void clr(){tot=0;memset(head,0,sizeof(head));}
inline void add(int u,int v){e[++tot]={v,head[u]},head[u]=tot;}
int dis[N],q[N];bool vis[N];
int spfa(){
fp(i,1,n+1)dis[i]=inf,vis[i]=0;
int h=0,t=1;dis[S]=0,q[h]=S;
while(h!=t){
int u=q[h++];vis[u]=0;if(h==N)h-=N;
go(u)if(dis[v]>dis[u]+1){
dis[v]=dis[u]+1;
if(!vis[v]){
q[t++]=v,vis[v]=1;
if(t==N)t-=N;
}
}
}return dis[T];
}
}G;
struct node{double x,y;}p[N];
struct line{
node a,b;int id;double sl;
inline line(){}
inline line(node a,node b,int id):a(a),b(b),id(id){sl=atan2(b.y-a.y,b.x-a.x);}
}q[N],a[N],l[N];
inline node operator +(node a,node b){return {a.x+b.x,a.y+b.y};}
inline node operator -(node a,node b){return {a.x-b.x,a.y-b.y};}
inline double operator *(node a,node b){return a.x*b.y-a.y*b.x;}
inline bool operator <(line a,line b){return a.sl==b.sl?(a.b-a.a)*(b.a-a.a)<=0:a.sl<b.sl;}
node inter(line a,line b){
double k1,k2,t;
k1=(b.b-a.a)*(a.b-a.a);
k2=(a.b-a.a)*(b.a-a.a);
t=k2/(k1+k2);
return {b.a.x+t*(b.b.x-b.a.x),b.a.y+t*(b.b.y-b.a.y)};
}
inline bool jd(line a,line b,line c){node p=inter(a,b);return (p-c.a)*(c.b-c.a)>0;}
void hpi(int st){
int tot=0;sort(l+1,l+1+m);
fp(i,1,m)if(l[i].sl!=a[tot].sl)a[++tot]=l[i];
int h=1,t=0;q[++t]=a[1],q[++t]=a[2];
fp(i,3,tot){
while(h<t&&jd(q[t-1],q[t],a[i]))--t;
while(h<t&&jd(q[h+1],q[h],a[i]))++h;
q[++t]=a[i];
}
while(h<t&&jd(q[t-1],q[t],q[h]))--t;
while(h<t&&jd(q[h+1],q[h],q[t]))++h;
fp(i,h,t)G.add(st,q[i].id);
}
void clr(){G.clr(),memset(no,0,sizeof(no));}
double dis(node a,node b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}
node rotate(node a){return {-a.y,a.x};}
node getmid(node a,node b){return {(a.x+b.x)/2,(a.y+b.y)/2};}
void init(int st){
l[1]=line({0,0},{sx,0},n+1),l[2]=line({sx,0},{sx,sy},n+1);
l[3]=line({sx,sy},{0,sy},n+1),l[4]=line({0,sy},{0,0},n+1);
m=4;
fp(i,1,n)if(i!=st&&!no[i]){
node mid=getmid(p[i],p[st]);
node v=rotate(p[i]-p[st]);
l[++m]=line(mid,mid+v,i);
}
}
void solve(){
clr(),n=read(),sx=read(),sy=read(),bx=read(),by=read();
node res={bx,by};
if(!n)return (void)(puts("0"));
T=n+1;int pos=0;double len=1e15;
fp(i,1,n){
p[i].x=read(),p[i].y=read();
if(p[i].x>sx||p[i].y>sy)no[i]=1;
double now=dis(p[i],res);
if(now<len)len=now,pos=i;
}S=pos;
fp(i,1,n)if(!no[i])init(i),hpi(i);
printf("%d\n",G.spfa());
}
int main(){
// freopen("testdata.in","r",stdin);
times=read();
while(times--)solve();
return 0;
}
P3297 [SDOI2013]逃考的更多相关文章
- 洛谷 P3297 [SDOI2013]逃考 解题报告
P3297 [SDOI2013]逃考 题意 给一个平面矩形,里面有一些有标号点,有一个是人物点,人物点会被最近的其他点控制,人物点要走出矩形,求人物点最少被几个点控制过. 保证一开始只被一个点控制,没 ...
- luogu P3297 [SDOI2013]逃考
传送门 gugugu 首先每个人管理的区域是一个多边形,并且整个矩形是被这样的多边形填满的.现在的问题是求一条经过多边形最少的路径到达边界,这个可以最短路. 现在的问题是建图,显然我们应该给相邻的多边 ...
- BZOJ3199 SDOI2013 逃考 半平面交、最短路
传送门 如果我们对于每一个点能找到与其相邻的点(即不经过其他点监视范围能够直接到达其监视范围的点)和是否直接到达边界,就可以直接BFS求最短路求出答案. 所以当前最重要的问题是如何找到对于每一个点相邻 ...
- Luogu3297 SDOI2013逃考(半平面交+最短路)
把每个人的监视范围看成点,相邻的两个监视范围连边,那么跑一遍最短路就可以了(事实上边权都为1可以直接bfs).显然存在最优路线没有某个时刻同时被多于两人监视,要到达另一个区域的话完全可以经过分界线而不 ...
- [JZOJ3297] 【SDOI2013】逃考
题目 我发现我现在连题面都懒得复制粘贴了-- 题目大意 在一个矩形中有一堆点,这堆点按照以下规则将矩形瓜分成一堆块: 对于每个坐标,它属于离它最近的点的块. 一个人从某个坐标出发到矩形外面,求经过的最 ...
- 【JZOJ3297】【SDOI2013】逃考(escape)
Mission 高考又来了,对于不认真读书的来讲真不是个好消息.为了小杨能在家里认真读书,他的亲戚决定驻扎在他的家里监督他学习,有爷爷奶奶.外公外婆.大舅.大嫂.阿姨-- 小杨实在是忍无可忍了,这种生 ...
- 2014秋C++第5周项目1參考-见识刚開始学习的人常见错误
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,实践要求见http://blog.csdn.net/sxhelijian/a ...
- C++常考面试题汇总
c++面试题 一 用简洁的语言描述 c++ 在 c 语言的基础上开发的一种面向对象编程的语言: 应用广泛: 支持多种编程范式,面向对象编程,泛型编程,和过程化编程:广泛应用于系统开发,引擎开发:支持类 ...
- AWS的SysOps认证考试样题解析
刚考过了AWS的developer认证,顺手做了一下SysOps的样题.以下是题目和答案. When working with Amazon RDS, by default AWS is respon ...
随机推荐
- 慕课笔记利用css进行布局【混合布局】
<html> <head> <title>混合布局学习</title> <style type="text/css"> ...
- 前端开发:JQuery(2)& Bootstrap
JS事件流 事件的概念:HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件.页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件. 事件流: ...
- cogs——7. 通信线路
7. 通信线路 ★★ 输入文件:mcst.in 输出文件:mcst.out 简单对比时间限制:1.5 s 内存限制:128 MB 问题描述 假设要在n个城市之间建立通信联络网,则连通n ...
- MySQL主从复制搭建教程收集(待实践)
先收集一下,后续再搭建测试. https://zhangge.net/4019.html http://www.cnblogs.com/jiangwenju/p/6098974.html http:/ ...
- mybatis collection标签和association标签(一对多,一对一)转载
mybatis 一对一与一对多collection和association的使用 在mybatis如何进行一对一.一对多的多表查询呢?这里用一个简单的例子说明. 一.一对一 1.associati ...
- 使用NPOI将DataTable生成Excel
听闻npoi 2.0版本支持excel2007格式了,表示期待其表现.不过目前还是使用1.2.5稳重点. 生活中有太多的列表都需要一个导出功能,当然这里的生活指的的程序员的生活.DataTable是从 ...
- Excel数据字典转换为PDM(且显示表名、字段相应的中文描写叙述)
在工作中遇到了一个问题就是把Excel数据字典转换为PDM. 可是转换完毕了全是英文,原来对表名.字段名的中文描写叙述就没有了. 且对于这个问题在powerdesigner15.2以后能够直接完毕.可 ...
- 静态链表的C++实现
静态链表是使用数组实现的能够高速插入和删除数据的链表,静态链表和链式单链表比的缺点在于链表的长度仅仅能初始化设置好,而相相应普通的顺序存储的链表,静态链表不能实现高速的读写随意的元素. 当然静态链表给 ...
- Python爬虫(一):基本概念
网络爬虫的定义 网络爬虫(Web Spider.又被称为网页蜘蛛.网络机器人,又称为网页追逐者),是一种依照一定的规则,自己主动的抓取万维网信息的程序或者脚本.另外一些不常使用的名字 ...
- 混合式框架-AgileLite
Agile Lite是一个HTML5移动前端框架.支持jQuery和Zepto双引擎.而且提供与UI无关的独立框架,内置了Flat UI样式和Ratchet样式.同一时候也支持单页模式和多页模式开发. ...