【NOI2018模拟5】三角剖分Bsh
【NOI2018模拟5】三角剖分Bsh
Description
给定一个正 n 边形及其三角剖分,共 2n - 3 条边 (n条多边形的边和n-3 条对角线),每条边的长度为 1。
共 q 次询问,每次询问给定两个点,求它们的最短距离。
Input
第一行一个整数 n ,表示多边形的点数;
接下来 n - 3 行,每行两个整数 ui,vi,表示一条 ai 和 bi 之间的对角线;
接下来一行一个整数 q,表示询问个数;
接下来 q 行,每行两个整数 xi,yi,表示第 i 次询问的起点和终点;
Output
对于每一个询问输出一个整数,表示答案。
Sample Input
6
1 5
2 4
5 2
5
1 3
2 5
3 4
6 3
6 6
Sample Output
2
1
1
3
0
\(n\leq 52000,1\leq q\leq 2n\)
因为这是个平面图,我们发现,选取一条边之后可以将图分为两个部分,两个部分之间的最短路一定经过了这条边的两个端点中至少一个。
又因为这是三角剖分,所以我们可以找到中间点使得左右两边的点数非常接近。所以我们可以分治。
代码:
#include<bits/stdc++.h>
#define ll long long
#define N 150000
using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
int n,m;
struct road {
int to,nxt;
}s[N<<1];
int h[N],cnt;
void add(int i,int j) {s[++cnt]=(road) {j,h[i]};h[i]=cnt;}
#define pr pair<int,int>
#define mp(a,b) make_pair(a,b)
bool vis[N];
int dis1[N],dis2[N];
queue<int>q;
void bfs(int S,int *dis) {
q.push(S);
dis[S]=0;
while(!q.empty()) {
int v=q.front();
q.pop();
for(int i=h[v];i;i=s[i].nxt) {
int to=s[i].to;
if(!vis[to]) continue ;
if(dis[to]>1e9) {
dis[to]=dis[v]+1;
q.push(to);
}
}
}
}
struct query {int x,y,id;};
int pre[N];
int ans[N];
int tag1[N],tag2[N];
int tim;
void solve(vector<int>V,vector<pr>E,vector<query>Q) {
if(!Q.size()) return ;
if(V.size()==3) {
for(int i=0;i<Q.size();i++) {
int x=Q[i].x,y=Q[i].y;
if(x==y) ans[Q[i].id]=0;
else ans[Q[i].id]=1;
}
return ;
}
int n=V.size(),m=E.size();
int mid=(n-2)>>1;
for(int i=0;i<n;i++) pre[V[i]]=0;
pre[V[0]]=1;
for(int i=1;i<n;i++) pre[V[i]]=pre[V[i-1]]+1;
int id;
int X=0,Y=0;
int MN=1e9;
for(int i=0;i<m;i++) {
int x=E[i].first,y=E[i].second;
int now=pre[y]-pre[x]-1;
if(max(now,n-2-now)<MN) {
MN=max(now,n-2-now);
X=x,Y=y;
}
}
vector<int>v1,v2;
vector<pr>e1,e2;
vector<query>q1,q2;
v1.clear(),e1.clear(),q1.clear();
v2.clear(),e2.clear(),q2.clear();
for(int i=0;i<n;i++) {
if(X<=V[i]&&V[i]<=Y) tag1[V[i]]=1;
if(V[i]>=Y||V[i]<=X) tag2[V[i]]=1;
}
for(int i=0;i<n;i++) {
if(tag1[V[i]]) v1.push_back(V[i]);
if(tag2[V[i]]) v2.push_back(V[i]);
}
for(int i=0;i<m;i++) {
int x=E[i].first,y=E[i].second;
if(tag1[x]&&tag1[y]) e1.push_back(E[i]);
if(tag2[x]&&tag2[y]) e2.push_back(E[i]);
}
for(int i=0;i<Q.size();i++) {
if(tag1[Q[i].x]&&tag1[Q[i].y]) q1.push_back(Q[i]);
if(tag2[Q[i].x]&&tag2[Q[i].y]) q2.push_back(Q[i]);
}
for(int i=0;i<n;i++) {
dis1[V[i]]=dis2[V[i]]=1e9+7;
vis[V[i]]=1;
}
bfs(X,dis1);
bfs(Y,dis2);
for(int i=0;i<Q.size();i++) {
int x=Q[i].x,y=Q[i].y,id=Q[i].id;
ans[id]=min(ans[id],dis1[x]+dis1[y]);
ans[id]=min(ans[id],dis2[x]+dis2[y]);
ans[id]=min(ans[id],dis1[x]+dis2[y]+1);
ans[id]=min(ans[id],dis2[x]+dis1[y]+1);
}
for(int i=0;i<n;i++) tag1[V[i]]=tag2[V[i]]=vis[V[i]]=0;
solve(v1,e1,q1),solve(v2,e2,q2);
}
vector<int>V;
vector<pr>E;
vector<query>Q;
int main() {
n=Get();
for(int i=1;i<n;i++) add(i,i+1),add(i+1,i);
add(1,n),add(n,1);
for(int i=1;i<=n-3;i++) {
int x=Get(),y=Get();
add(x,y),add(y,x);
if(x>y) swap(x,y);
E.push_back(mp(x,y));
}
memset(ans,0x3f,sizeof(ans));
for(int i=1;i<=n;i++) V.push_back(i);
m=Get();
for(int i=1;i<=m;i++) {
int x=Get(),y=Get();
if(x>y) swap(x,y);
Q.push_back((query) {x,y,i});
}
solve(V,E,Q);
for(int i=1;i<=m;i++) cout<<ans[i]<<"\n";
return 0;
}
【NOI2018模拟5】三角剖分Bsh的更多相关文章
- BSOJ5458 [NOI2018模拟5]三角剖分Bsh 分治最短路
题意简述 给定一个正\(n\)边形及其三角剖分,每条边的长度为\(1\),给你\(q\)组询问,每次询问给定两个点\(x_i\)至\(y_i\)的最短距离. 做法 显然正多边形的三角剖分是一个平面图, ...
- JZOJ 5602.【NOI2018模拟3.26】Cti
JZOJ 5602.[NOI2018模拟3.26]Cti Description 有一个 \(n×m\) 的地图,地图上的每一个位置可以是空地,炮塔或是敌人.你需要操纵炮塔消灭敌人. 对于每个炮塔都有 ...
- 【NOI2018模拟】Yja
[NOI2018模拟]Yja Description 在平面上找\(n\)个点,要求这 \(n\)个点离原点的距离分别为 \(r1,r2,...,rn\) .最大化这\(n\) 个点构成的凸包面积,凸 ...
- 【JZOJ5605】【NOI2018模拟3.26】Arg
题目描述 给出一个长度为 m 的序列 A, 请你求出有多少种 1...n 的排列, 满足 A 是它的一个 LIS. 解题思路 如何求出一个序列的LIS? 对于二分的方法,每次插入一个数,将它放到第一个 ...
- 【JZOJ5603】【NOI2018模拟3.27】Xjz
题目描述 给定字符串 S 和 T. 串A和串B匹配的定义改为:存在一个字符的映射,使得A应用这个映射之后等于B,且这个映射必须为一个排列. A=121, B=313,当映射为{1->3, 2-& ...
- NOIP2018 模拟赛(二十二)雅礼NOI
Preface 这次的题目都是NOI+的题,所以大家的分数都有点惨烈. 依靠T1大力骗分水到Rank2 所以想看正解的话看这里吧 A. 「雅礼NOI2018模拟赛(一) Day1」树 看一眼题目感觉十 ...
- 【XSY2968】线性代数
题目来源:noi2018模拟测试赛(二十二) 毒瘤板题+提答场……真tm爽 提答求最大团,各路神仙退火神仙随机化八仙过海 题意: 题解: 支持双端插入的回文自动机板题 代码: #include< ...
- 【XSY2892】【GDSOI2018】谁是冠军
题目来源:noi2018模拟测试赛(二十三)T3 san 为什么noi模拟赛里会做到省选原题啊…… 题意: Description 有n个人,简单起见把他们编号为1到n,每个人有三项指标分别是攻击力, ...
- 【XSY2989】字符串
题目来源:NOI2018模拟测试赛(二十六) 题解: 首先由于这是个01串,所以反对称串的意思就是这个字符串的后半部分是前半部分的反转且翻转结果: 一个串出现有三种情况:在前半部分,在后半部分或穿过中 ...
随机推荐
- 服务器文档下载zip格式
刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Core.Utility;@{ s ...
- 如何把ASP.NET MVC项目部署到本地IIS上
默认情况下,在VisualStudio中开发网站,会运行在IISExpress中,如果想把网站部署到本地的IIS服务器上该怎么办呢? 一.首先,以管理员身份运行VisualStudio,否则在修改项目 ...
- 47.Linux-DEVICE_ATTR()介绍及使用示例
1.介绍 使用DEVICE_ATTR,可以实现驱动在sys目录自动创建文件,我们只需要实现show和store函数即可. 然后在应用层就能通过cat和echo命令来对sys创建出来的文件进行读写驱动设 ...
- P9架构师讲解从单机至亿级流量大型网站系统架构的演进过程
阶段一.单机构建网站 网站的初期,我们经常会在单机上跑我们所有的程序和软件.此时我们使用一个容器,如tomcat.jetty.jboos,然后直接使用JSP/servlet技术,或者使用一些开源的框架 ...
- python中的tcp
目录 TCP简介 TCP介绍 TCP特点 TCP与UDP的不同点 udp通信模型 TCP通信模型 tcp客户端 tcp服务器 tcp注意点 TCP简介 TCP介绍 TCP协议,传输控制协议(英语:Tr ...
- JavaScript中的三种弹窗
---恢复内容开始--- 1.警告窗口(alert) <script type="text/javascript"> alert("我是警告弹框!" ...
- 51单片机:IO口扩展芯片用法(74HC165,74HC595)
IO口扩展芯片,主要是解决单片机IO口太少. 74HC165:数据从并转串 74HC595:数据从串转并 两种芯片,都是通过时序电路,加上移位功能,进行数据传输 74HC165:数据从并转串.以下实例 ...
- js循环json得到 键和值
var jsondata=[{"男":4,"女":3,"不详":0},{"男one":23,"女two&quo ...
- 为链表数据结构实现iterator接口
iterator作用 为所有的数据结构提供统一的访问方式. 接口对象 接口对象一共有3个方法,next()方法.return()方法.throw()方法. next() 必填 用于for..of迭代. ...
- bootstrap timepicker 在angular中取值赋值 并转化为时间戳
上一篇我们讲到angular对于timepicker的一个封装后的插件angular-bootstrap-timepicker,但是由于angular的版本必须是v1.2.30以上的.对于有些涉及到多 ...