Description

给定一个凸n边形,以及它的三角剖分。再给定q个询问,每个询问是一对凸多边行上的顶点(a,b),问点a最少经过多少条边(可以是多边形上的边,也可以是剖分上的边)可以到达点b。

Input

第一行一个整数n(n <= 50000),代表有n个点。点1,2,3,…,n是凸多边形上是顺时针排布的。

接下来n-3行,每行两个整数(x,y),代表(x,y)之间有一条剖分边。
接下来是一个整数q(q <= 100000),代表有q组询问。
接下来q行是两个整数(a,b)。

Output

输出q行,每行一个整数代表最少边数。
类似边分治,每次选一条边将多边形分为两部分,处理经过边的端点的路线,递归分治
#include<bits/stdc++.h>
char buf[],*ptr=buf+;
int G(){
if(ptr-buf==)fread(ptr=buf,,,stdin);
return *ptr++;
}
int _(){
int x=;
if(ptr-buf<){
while(*ptr<)++ptr;
while(*ptr>)x=x*+*ptr++-;
}else{
int c=G();
while(c<)c=G();
while(c>)x=x*+c-,c=G();
}
return x;
}
const int N=,inf=0x3f3f3f3f,P=;
int n,qp,idp=;
int deg[N],q[N],ql=,qr=,as[N];
std::vector<int>e0[N],ee[N];
struct Q{int w,id;};
std::vector<Q>qq[N];
Q*qs[N][];
int sz[N],*lr[N][],*et[N][];
int p3[N][];
void ae(int a,int b){
++deg[b];++deg[a];
e0[a].push_back(b);
e0[b].push_back(a);
} struct hash_map{
int h[P][];
int*operator()(int a,int b){
if(a>b)std::swap(a,b);
int w=(a*+b*)%P;
while(h[w][]){
if(h[w][]==a&&h[w][]==b)return h[w]+;
if((w+=)>=P)w-=P;
}
h[w][]=a,h[w][]=b;
return h[w]+;
}
}h1,h2;
void chk(int a,int b){
if(a>b)std::swap(a,b);
if(a==&&b==n||a+==b)return;
int*w=h1(a,b);
if(w[]){
int x=idp,y=w[];
ee[x].push_back(y);
ee[y].push_back(x);
int*c=h2(x,y);
c[]=a;c[]=b;
}else w[]=idp;
}
int ss[N][],sp,tk=,ed[N],ed2[N];
int ps[N],pp=;
void ins(int a){
for(int t=;t<;++t){
int w=p3[a][t];
if(ed2[w]!=tk)ed2[ps[pp++]=w]=tk;
}
}
void f2(int w,int pa){
sz[w]=;
ed[w]=tk;
ss[sp][]=w,ss[sp++][]=pa;
for(int*l=lr[w][],*r=lr[w][];l!=r;++l){
int u=*l;
if(u==pa)continue;
f2(u,w);
sz[w]+=sz[u];
}
}
void dele(int a,int b){
for(int*l=lr[a][],*r=lr[a][];l!=r;++l)if(*l==b){
*l=*--lr[a][];
return;
}
}
int min(int a,int b){return a<b?a:b;}
void mins(int&a,int b){if(a>b)a=b;}
int d1[N],d2[N],dd1[N],dd2[N],dk=;
bool qd[N];
void bfs(int w,int*d,int*dd){
ql=qr=;
dd[q[++qr]=w]=dk,d[w]=;
while(ql!=qr){
w=q[++ql];
for(int*l=et[w][],*r=et[w][];l!=r;++l){
int u=*l;
if(ed2[u]==tk&&dd[u]!=dk)dd[q[++qr]=u]=dk,d[u]=d[w]+;
}
}
}
void f1(int w){
++tk;
pp=;
sp=;
f2(w,);
int SZ=sz[w];
if(SZ>){
int mx=,p1=w,p2=;
for(int i=;i<sp;++i){
int u=ss[i][],mv=min(sz[u],SZ-sz[u]);
if(mv>mx)mx=mv,p1=u,p2=ss[i][];
ins(u);
}
dele(p1,p2);
dele(p2,p1);
int*ns=h2(p1,p2);
++dk;
bfs(ns[],d1,dd1);bfs(ns[],d2,dd2);
for(int i=;i<pp;++i){
int u=ps[i];
int d1u=d1[u];
int d2u=d2[u];
for(Q*l=qs[u][],*r=qs[u][];l!=r;++l){
int v=l->w;
if(qd[v])*l--=*(qs[u][]=--r);
else if(ed2[v]==tk){
int d1v=d1[v];
int d2v=d2[v];
mins(as[l->id],min(min(d1u+d1v,d2u+d2v),min(d1u+d2v+,d2u+d1v+)));
}
}
}
qd[ns[]]=qd[ns[]]=;
for(int d=;d<;++d)qs[ns[d]][]=qs[ns[d]][];
f1(p1);f1(p2);
}
}
int main(){
n=_();
for(int i=,a,b;i<=n-;++i){
a=_();b=_();
ae(a,b);
}
for(int i=;i<=n;++i)ae(i,i==n?:i+);
for(int i=;i<=n;++i){
et[i][]=e0[i].data();
et[i][]=et[i][]+e0[i].size();
}
for(int i=;i<=n;++i)if(deg[i]==)q[++qr]=i;
while(ql!=qr){
int w=q[++ql];
if(deg[w]!=)break;
deg[w]=;
int cs[],cp=;
cs[cp++]=w;
for(int*l=et[w][],*r=et[w][];l!=r;++l){
int u=*l;
if(!deg[u])continue;
cs[cp++]=u;
if(==--deg[u])q[++qr]=u;
}
++idp;
for(int i=;i<;++i){
for(int j=;j<i;++j)chk(cs[i],cs[j]);
p3[idp][i]=cs[i];
}
}
for(int i=;i<=idp;++i){
lr[i][]=ee[i].data();
lr[i][]=lr[i][]+ee[i].size();
}
qp=_();
for(int i=;i<qp;++i){
int x=_(),y=_();
if(x==y)continue;
if(x>y)std::swap(x,y);
if(x==&&y==n||x+==y||h1(x,y)[]){
as[i]=;
continue;
}
as[i]=inf;
qq[x].push_back((Q){y,i});
qq[y].push_back((Q){x,i});
}
for(int i=;i<=idp;++i){
qs[i][]=qq[i].data();
qs[i][]=qs[i][]+qq[i].size();
}
f1();
for(int i=;i<qp;++i)printf("%d\n",as[i]);
return ;
}

bzoj 4449: [Neerc2015]Distance on Triangulation的更多相关文章

  1. 【bzoj 4449】[Neerc2015]Distance on Triangulation

    Description 给定一个凸n边形,以及它的三角剖分.再给定q个询问,每个询问是一对凸多边行上的顶点(a,b),问点a最少经过多少条边(可以是多边形上的边,也可以是剖分上的边)可以到达点b. I ...

  2. 【BZOJ 4449】[Neerc2015]Distance on Triangulation 多边形分治结构

    这题好神啊……正解方向是分治,据我所知的分治方法有:I.离线后直接对多边形以及所有的询问进行分治 II.建立多边形的分治结构(对于三角形来说类似线段树,对于对角线来说类似平衡树),然后每次在这个分治结 ...

  3. BZOJ4449 : [Neerc2015]Distance on Triangulation

    首先拓扑,每次取出度数为$2$的点,这样可以把所有三角形都找到. 那么建出对偶图,会发现是一棵树. 对这棵树进行点分治,每次取出重心,DFS求出所有在里面的点,然后从重心$3$个点分别做一次BFS. ...

  4. Gym 100851 Distance on Triangulation

    题意:给你一个N边形, 然后这个n边形有n-3条边,然后询问2点之间的最短路. 题解:分治. 我们可以找到一条边,使得这幅图能分成大小相同的2幅图,那么我们就可以确定那些被分割开的询问的答案是多少了. ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. NOIP模拟赛 城市

    题目描述 $ZZQ$ 是一国之主. 这个国家有$N$个城市, 第$i$个城市与第$(i + 1) (mod N)$和$(i - 1) (mod N)$在一个正$N$边形相连. $ZZQ$ 又新建了$N ...

  7. Week Two

    2018.12.3: 1.[BZOJ 4819] 2.[BZOJ 4827] 3.[P1919] 4.[FFT模板] 2018.12.4: 1.[NTT] 2.[MTT(CRT)] 3.[MTT(my ...

  8. NEERC15

    2015-2016 ACM-ICPC Northeastern European Regional Contest 再开一个新坑吧 目前姿势有限,C.H.I仍然处于弃坑状态 代码戳这里 Problem ...

  9. 【刷题】BZOJ 3365 [Usaco2004 Feb]Distance Statistics 路程统计

    Description 在得知了自己农场的完整地图后(地图形式如前三题所述),约翰又有了新的问题.他提供 一个整数K(1≤K≤109),希望你输出有多少对农场之间的距离是不超过K的. Input 第1 ...

随机推荐

  1. [转载]JS浏览器兼容性问题

    from:http://dada-fangfang.iteye.com/blog/811749 做BS开发就难免会用到javascript,而每个浏览器对javascript的支持有不同.这就需要我们 ...

  2. 形成一个zigzag数组(JPEG编码里取像素数据的排列顺序)

    面试例题:输入n,求一个nXn矩阵,规定矩阵沿45度递增,形成一个zigzag数组(JPEG编码里取像素数据的排列顺序),请问如何用C++实现? (中国台湾著名硬件公司2007年11月面试题)(自程序 ...

  3. 福大软工 1816:项目UML设计(团队作业三)

    项目UML设计(团队) 团队信息 团队名:第三视角 各成员学号及姓名 姓名 学号 博客链接 张扬(组长) 031602345 http://www.cnblogs.com/sxZhangYang/p/ ...

  4. JSONField解决序列化与反序列化字段匹配问题

    需求:调用第三方数据,数据格式为Json,并提供一个接口将获取的第三方数据给本公司其他部门调用. 处理流程:第三方Json--反序列化实体--保存到本地数据库--查询数据--序列化Json数据供本公司 ...

  5. avalon 路由问题

    1, 直接使用avalon的 amd加载器, 可以不需要 require.js 2, 配置baseUrl 路径, 这个一定要在 js所在的目录,  而不是jsp所在的目录,  如果js 和jsp分开 ...

  6. IOS的各种控件(转载,防止遗忘)

    UITextView控件的详细讲解 感觉写的相当不错,而且很全就直接转载了 1.创建并初始化 创建UITextView的文件,并在.h文件中写入如下代码: #import <UIKit/UIKi ...

  7. Influxdb简单实用操作

    新的infludb版本已经取消了页面的访问方式,只能使用客户端来查看数据 一.influxdb与传统数据库的比较 库.表等比较: influxDB 传统数据库中的概念 database 数据库 mea ...

  8. pandas 操作 excel

    1. 多重 sheet Using Pandas to pd.read_excel() for multiple worksheets of the same workbook pd.read_exc ...

  9. 大家一起做训练 第一场 E Number With The Given Amount Of Divisors

    题目来源:CodeForce #27 E 题目意思和题目标题一样,给一个n,求约数的个数恰好为n个的最小的数.保证答案在1018内. Orz,这题训练的时候没写出来. 这道题目分析一下,1018的不大 ...

  10. 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(二)-- Web Api Demo

    在上一篇里,我已经建立了一个简单的Web-Demo应用程序.这一篇将记录将此Demo程序改造成一个Web Api应用程序. 一.添加ASP.NET Core MVC包 1. 在project.json ...