bzoj 4449: [Neerc2015]Distance on Triangulation
Description
给定一个凸n边形,以及它的三角剖分。再给定q个询问,每个询问是一对凸多边行上的顶点(a,b),问点a最少经过多少条边(可以是多边形上的边,也可以是剖分上的边)可以到达点b。
Input
第一行一个整数n(n <= 50000),代表有n个点。点1,2,3,…,n是凸多边形上是顺时针排布的。
Output
#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的更多相关文章
- 【bzoj 4449】[Neerc2015]Distance on Triangulation
Description 给定一个凸n边形,以及它的三角剖分.再给定q个询问,每个询问是一对凸多边行上的顶点(a,b),问点a最少经过多少条边(可以是多边形上的边,也可以是剖分上的边)可以到达点b. I ...
- 【BZOJ 4449】[Neerc2015]Distance on Triangulation 多边形分治结构
这题好神啊……正解方向是分治,据我所知的分治方法有:I.离线后直接对多边形以及所有的询问进行分治 II.建立多边形的分治结构(对于三角形来说类似线段树,对于对角线来说类似平衡树),然后每次在这个分治结 ...
- BZOJ4449 : [Neerc2015]Distance on Triangulation
首先拓扑,每次取出度数为$2$的点,这样可以把所有三角形都找到. 那么建出对偶图,会发现是一棵树. 对这棵树进行点分治,每次取出重心,DFS求出所有在里面的点,然后从重心$3$个点分别做一次BFS. ...
- Gym 100851 Distance on Triangulation
题意:给你一个N边形, 然后这个n边形有n-3条边,然后询问2点之间的最短路. 题解:分治. 我们可以找到一条边,使得这幅图能分成大小相同的2幅图,那么我们就可以确定那些被分割开的询问的答案是多少了. ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- NOIP模拟赛 城市
题目描述 $ZZQ$ 是一国之主. 这个国家有$N$个城市, 第$i$个城市与第$(i + 1) (mod N)$和$(i - 1) (mod N)$在一个正$N$边形相连. $ZZQ$ 又新建了$N ...
- 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 ...
- NEERC15
2015-2016 ACM-ICPC Northeastern European Regional Contest 再开一个新坑吧 目前姿势有限,C.H.I仍然处于弃坑状态 代码戳这里 Problem ...
- 【刷题】BZOJ 3365 [Usaco2004 Feb]Distance Statistics 路程统计
Description 在得知了自己农场的完整地图后(地图形式如前三题所述),约翰又有了新的问题.他提供 一个整数K(1≤K≤109),希望你输出有多少对农场之间的距离是不超过K的. Input 第1 ...
随机推荐
- Drawing house
截图如下: 代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> & ...
- CCleaner 垃圾文件清理规则 编写指南
以下内容的英文版本来源于 CCleaner 官方论坛,仅供参考.欢迎大家编写并分享针对常用国产软件的垃圾文件清理规则!需要说明的是规则文件(Winapp2.ini)需和程序文件放于同一文件夹下,才能被 ...
- SharePoint 会话(Session)状态和状态服务
1. 启用会话状态 Enable-SPSessionStateService –DefaultProvision 或 Enable-SPSessionStateService –DatabaseNam ...
- avalon 路由问题
1, 直接使用avalon的 amd加载器, 可以不需要 require.js 2, 配置baseUrl 路径, 这个一定要在 js所在的目录, 而不是jsp所在的目录, 如果js 和jsp分开 ...
- 部署python3.6下的django
首先是安装好nginx,配置web目录,配置文件在confi.d中, server { # the port your site will be served on listen ; # the do ...
- grafana的一些坑
坑1: 在设置alert的时候template中的变量是不被支持的,警告如下: 解决办法: 使用不带变量的具体sql查询 坑2: 时间轴的设置: 在更早的版本中时间轴的locale是无法设置的,就是说 ...
- 高强度减脂Tabata练习
每个动作20秒 动作间休息10秒 8个动作为一组 每次做四组 让你大汗淋漓全身酸爽 波比跳 ▼ 跳起箭步蹲 ▼ 登山者 ▼ 俯卧撑 ▼ 卷腹 ▼ 开合跳 ▼ 高抬腿 ▼ 俄罗斯转体 ▼ Bingo ▼ ...
- C++ 和 Java 对类继承的差异
#include <iostream> using namespace std; class Base { public: int i; Base() { i = ; fun(); } v ...
- 【linux】如何退出shell终端
退出shell终端: exit + 回车即可 清除当前屏幕信息 clear 不过clear只是将之前的命令向上隐藏啦...
- zookeeper windows 下配置和基础命令
原文链接:http://blog.csdn.net/woshioosm/article/details/45560177 1, 解压zookeeper ,在目录下建立文件夹 data 和log 2,在 ...