这题好神啊……
正解方向是分治,据我所知的分治方法有:I.离线后直接对多边形以及所有的询问进行分治 II.建立多边形的分治结构(对于三角形来说类似线段树,对于对角线来说类似平衡树),然后每次在这个分治结构上进行查询 III.将原图转为其对偶图(利用拓扑),发现是一棵树,然后在这棵树上进行分治(似乎也有离线分治和在线建立分治结构两种方法)
我用的是第二种方法,感觉写起来不是很容易,但是也并不恶心,具体实现以及具体问题的处理方法见代码.
感觉这样分治的复杂度是log的,实际证明最坏情况下存在使得任意一侧的三角形数不少于n/3的分发,然而并不会证,大该感性理解一下吧.
思维笔记:I.分治无处不在 II.分治就是分治,也可以没有信息的合并 III.分治的出发点也可以是砍半,就像二分一样 IV.分治结构的建立类似分治,而分治结构的使用更像是二分
算法笔记:I.建立分治结构时所需信息,以及分治结构所需维护的信息,是不一样的,分开考虑与处理会方便得多 II.在分治结构中,储存信息的方式可以是对于每个点存储其在每一层的信息,也可以是对于每一层存储每个点的信息,两者各有千秋,在这道题里,个人感觉前者用起来更加方便 III.这道题分治的理由我感觉是——一个对角线把多边形切成两个部分,如果询问的两个点都在这两个部分里的其中一个里面,那这次询问一定与另一部分无关

#pragma GCC optimize("O3")
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define pb push_back
#define ft first
#define sd second
#define mmp(a,b) (std::make_pair(a,b))
char xB[(<<)+],*xS,*xT;
#define gtc (xS==xT&&(xT=((xS=xB)+fread(xB,1,1<<15,stdin)),xS==xT)?0:*xS++)
inline void read(int &x){
register char ch=gtc;
for(x=;ch<''||ch>'';ch=gtc);
for(;ch>=''&&ch<='';x=(x<<)+(x<<)+ch-'',ch=gtc);
}
typedef std::pair<int,int> pii;
typedef std::vector<int> vi;
typedef std::vector<pii> vii;
const int A=,N=,Inf=0x3f3f3f3f;
vi tmp1;
vii tmp2;
struct Block{
Block *ch[];
pii cut;
}*root,block[N<<];
#define newblock (block+(sz++))
int to[N][A],dis[N][A][];
int q[N],front,back,vis[N],id[N];
int n;
struct V{int to,next;}c[N<<];
int head[N],t;
inline void add(int x,int y){
c[++t].to=y,c[t].next=head[x],head[x]=t;
c[++t].to=x,c[t].next=head[y],head[y]=t;
}
int sz,cnt;
inline void bfs(int S,int deep,int opt){
++cnt,front=back=,q[back++]=S;
dis[S][deep][opt]=,vis[S]=cnt;
register int x,i;
while(front!=back){
x=q[front++];
for(i=head[x];i;i=c[i].next)
if(vis[c[i].to]!=cnt){
vis[c[i].to]=cnt;
dis[c[i].to][deep][opt]=dis[x][deep][opt]+;
q[back++]=c[i].to;
}
}
}
inline void build(Block *&p,register vi poi,register vii cut,int deep){
p=newblock;
if(cut.size()==)return;
pii mini;
int min=Inf,temp,size1=poi.size(),size2=cut.size();
register int i;
for(i=;i<size2;++i){
temp=std::abs(id[cut[i].ft]-id[cut[i].sd])+;
temp=std::max(temp,size1-temp+);
if(temp<min)
min=temp,mini=cut[i];
}
p->cut=mini;
int l=id[mini.ft],r=id[mini.sd];
if(l>r)std::swap(l,r);
tmp1.clear(),tmp2.clear();
for(i=;i<=l;++i){
tmp1.pb(poi[i]);
id[poi[i]]=tmp1.size()-;
to[poi[i]][deep]=;
}
for(i=r;i<size1;++i){
tmp1.pb(poi[i]);
id[poi[i]]=tmp1.size()-;
to[poi[i]][deep]=;
}
for(i=;i<size2;++i){
if(cut[i]==mini)continue;
if(to[cut[i].ft][deep]==&&to[cut[i].sd][deep]==)
tmp2.pb(cut[i]);
}
build(p->ch[],tmp1,tmp2,deep+);
tmp1.clear(),tmp2.clear();
for(i=l;i<=r;++i){
tmp1.pb(poi[i]);
id[poi[i]]=i-l;
to[poi[i]][deep]=;
}
for(i=;i<size2;++i){
if(cut[i]==mini)continue;
if(to[cut[i].ft][deep]==&&to[cut[i].sd][deep]==)
tmp2.pb(cut[i]);
}
build(p->ch[],tmp1,tmp2,deep+);
for(i=;i<size1;++i)head[poi[i]]=;
t=;
for(i=;i<size1;++i)
add(poi[i],poi[i-]);
add(poi[size1-],poi[]);
for(i=;i<size2;++i)
add(cut[i].ft,cut[i].sd);
bfs(mini.ft,deep,);
bfs(mini.sd,deep,);
}
inline int query(Block *p,int x,int y,int deep){
if(!p->ch[])return ;
if(p->cut.ft==x)return dis[y][deep][];
if(p->cut.sd==x)return dis[y][deep][];
if(p->cut.ft==y)return dis[x][deep][];
if(p->cut.sd==y)return dis[x][deep][];
if(to[x][deep]==to[y][deep])return query(p->ch[to[x][deep]],x,y,deep+);
int ret=dis[x][deep][]+dis[y][deep][];
ret=std::min(ret,dis[x][deep][]+dis[y][deep][]);
return ret;
}
int main(){
read(n);
register int i;pii rio;
for(i=;i<=n;++i)
tmp1.pb(i),id[i]=i-;
for(i=;i<=n-;++i)
read(rio.ft),read(rio.sd),tmp2.pb(rio);
build(root,tmp1,tmp2,);
int T,x,y;
read(T);
while(T--){
read(x),read(y);
printf("%d\n",x==y?:query(root,x,y,));
}
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

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

  3. BZOJ4449 : [Neerc2015]Distance on Triangulation

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

  4. BZOJ 4012 HNOI2015 开店 树的边分治+分治树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4012 题意概述:给出一颗N点的树,保证树上所有点的度不超过3,树上每个点有权值,每条边有权 ...

  5. POJ 1987 BZOJ 3365 Distance Statistics 树的分治(点分治)

    题目大意:(同poj1741,刷一赠一系列) CODE: #include <cstdio> #include <cstring> #include <iostream& ...

  6. BZOJ.4738.[清华集训2016]汽水(点分治 分数规划)

    BZOJ UOJ 记\(val_i\)是每条边的边权,\(s\)是边权和,\(t\)是经过边数,\(k\)是给定的\(k\). 在点分治的时候二分答案\(x\),设\(|\frac st-k|=x\) ...

  7. NOI 2007 货币兑换Cash (bzoj 1492) - 斜率优化 - 动态规划 - CDQ分治

    Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...

  8. CodeChef - PRIMEDST Prime Distance On Tree 树分治 + FFT

    Prime Distance On Tree Problem description. You are given a tree. If we select 2 distinct nodes unif ...

  9. bzoj 3784: 树上的路径【点分治+st表+堆】

    参考:https://www.cnblogs.com/CQzhangyu/p/7071477.html 神奇的点分治序(或者叫点剖?).就是把点分治扫过的点依次放进队列里,然后发现,对于每一棵树摊到序 ...

随机推荐

  1. Openstack 10 云环境安装

    概述 资源规划 Undercloud Installation Overcloud Installation Trouble Shooting 附录 本指南介绍了如何使用 Red Hat OpenSt ...

  2. 如何停止AAD服务

    Connect-MsolService (Get-MSOLCompanyInformation).DirectorySynchronizationEnabled 用这个命令查看是enable还是Dis ...

  3. Hands on Machine Learning with sklearn and TensorFlow —— 一个完整的机器学习项目(加州房地产)

    数据集地址:https://github.com/ageron/handson-ml/tree/master/datasets 先行知识准备:NumPy,Pandas,Matplotlib的模块使用 ...

  4. scrapy-redis+selenium+webdriver 部署到linux上

    背景:在使用selenium时,在本地使用windows,都会有一个图形界面,但是到了生产环境linux上没有了图形界面怎么部署呢? 解决方案: 1.安装图形化界面,不推荐,因为安装图形化界面会占用很 ...

  5. 经验之谈:10位顶级PHP大师的开发原则

    导读:在Web开发世界里,PHP是最流行的语言之一,从PHP里,你能够很容易的找到你所需的脚本,遗憾的是,很少人会去用“最佳做法”去写一个PHP程序.这里,我们向大家介绍PHP的10种最佳实践,当然, ...

  6. vim 编码方式的设置

    和所有的流行文本编辑器一样,Vim 可以很好的编辑各种字符编码的文件,这当然包括UCS-2.UTF-8 等流行的 Unicode 编码方式.然而不幸的是,和很多来自 Linux 世界的软件一样,这需要 ...

  7. c# webBrowser打开pdf问题

    1.生成模式使用release加*86尝试,使用debug则webBrowser不生效

  8. python爬虫调用搜索引擎及图片爬取实战

    实战三-向搜索引擎提交搜索请求 关键点:利用搜索引擎提供的接口 百度的接口:wd="要搜索的内容" 360的接口:q="要搜索的内容" 所以我们只要把我们提交给 ...

  9. P4语法(4)Control block

    Control block Control block之中用于放置设计好的Table和Action. 可以把control block认为是pipeline的一个模板,之前用的v1model中就是in ...

  10. 团队项目选题报告(I know)

    一.团队成员及分工 团队名称:I know 团队成员: 陈家权:选题报告word撰写 赖晓连:ppt制作,原型设计 雷晶:ppt制作,原型设计 林巧娜:原型设计,博客随笔撰写 庄加鑫:选题报告word ...