[点分治 离线] BZOJ 4449 [Neerc2015]Distance on Triangulation
2017-03-06 20:43
651 查看
其实简单的找一条边然后分成两半
被我硬生生写成对偶图点分治分成三块 233
就把所有询问一起处理
点分治时 如果两个点在同一侧 就递归 否则对三个点bfs就能知道最短路径
被我硬生生写成对偶图点分治分成三块 233
就把所有询问一起处理
点分治时 如果两个点在同一侧 就递归 否则对三个点bfs就能知道最短路径
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<map> #include<vector> #define cl(x) memset(x,0,sizeof(x)) using namespace std; typedef pair<int,int> abcd; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } const int N=100005; struct edge{ int u,v,next; }G[N<<3]; int head ,head2 ,inum; inline void add(int u,int v,int *head){ int p=++inum; G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p; } inline void link(int u,int v,int *head){ add(u,v,head); add(v,u,head); } #define V G[p].v int n; int deg ; int pt [3]; map<abcd,int> ed; inline void BT(){ static int Q ,l,r,rem ; l=r=-1; cl(rem); for (int i=1;i<=n;i++) if (deg[i]==2) Q[++r]=i; for (int i=1;i<=n-2;i++){ int u=Q[++l],a[3]; rem[u]=1; *a=0; for (int p=head[u];p;p=G[p].next) if (!rem[V]) a[++*a]=V; pt[i][0]=u; pt[i][1]=a[1]; pt[i][2]=a[2]; if ((--deg[a[1]])==2) Q[++r]=a[1]; if ((--deg[a[2]])==2) Q[++r]=a[2]; } for (int s=1;s<=n-2;s++){ for (int i=0;i<3;i++) for (int j=0;j<i;j++){ int u=pt[s][i],v=pt[s][j]; if (u>v) swap(u,v); if (ed.count(abcd(u,v))) link(s,ed[abcd(u,v)],head2); else ed[abcd(u,v)]=s; } } } int del ; int sum,minv,rt; int size ; inline void Root(int u,int fa){ size[u]=1; int maxv=0; for (int p=head2[u];p;p=G[p].next) if (V!=fa && !del[V]) Root(V,u),size[u]+=size[V],maxv=max(maxv,size[V]); maxv=max(maxv,sum-size[u]); if (maxv<minv) minv=maxv,rt=u; } int c ,col=4; int ins ,clk; int dis[3] ; inline void bfs(int S,int *dis){ static int Q ,l,r; l=r=-1; ++clk; Q[++r]=S; dis[S]=0; ins[S]=clk; while (l<r){ int u=Q[++l]; for (int p=head[u];p;p=G[p].next) if (c[V]==c[u] && ins[V]!=clk){ dis[V]=dis[u]+1; ins[V]=clk; Q[++r]=V; } } } int Col; inline void color(int u,int fa){ size[u]=1; for (int i=0;i<3;i++) c[pt[u][i]]=Col; for (int p=head2[u];p;p=G[p].next) if (V!=fa && !del[V]) color(V,u),size[u]+=size[V]; } struct event{ int u,v,idx; event(int u=0,int v=0,int idx=0):u(u),v(v),idx(idx){ } }; int Ans[N<<1]; inline void Divide(int u,vector<event> &que){ if (que.empty()) return; del[u]=1; for (int i=0;i<3;i++) bfs(pt[u][i],dis[i]); Col=0; for (int p=head2[u];p;p=G[p].next) if (!del[V]){ Col++; color(V,0); } for (int i=0;i<3;i++) c[pt[u][i]]=0; vector<event> vec[4]; for (int i=0;i<(int)que.size();i++){ int a=que[i].u,b=que[i].v,idx=que[i].idx; if (c[a]==0){ for (int j=0;j<3;j++) if (a==pt[u][j]) Ans[idx]=dis[j][b]; }else if (c[b]==0){ for (int j=0;j<3;j++) if (b==pt[u][j]) Ans[idx]=dis[j][a]; }else if (c[a]!=c[b]){ Ans[idx]=1<<30; for (int j=0;j<3;j++) Ans[idx]=min(Ans[idx],dis[j][a]+dis[j][b]); }else{ vec[c[a]].push_back(que[i]); } } for (int p=head2[u],i=0;p;p=G[p].next) if (!del[V]){ Col=++col; color(V,0); sum=size[V]; minv=1<<30; Root(V,0); Divide(rt,vec[++i]); } } int main(){ int iu,iv,Q; freopen("drive.in","r",stdin); freopen("drive.out","w",stdout); read(n); for (int i=1;i<n;i++) link(i,i+1,head); link(n,1,head); for (int i=1;i<=n;i++) deg[i]=2; for (int i=1;i<=n-3;i++) read(iu),read(iv),link(iu,iv,head),deg[iu]++,deg[iv]++; BT(); read(Q); vector<event> vec; for (int i=1;i<=Q;i++) read(iu),read(iv),vec.push_back(event(iu,iv,i)); sum=n-2; minv=1<<30; Root(1,0); for (int i=1;i<=n;i++) c[i]=col; Divide(rt,vec); for (int i=1;i<=Q;i++) printf("%d\n",Ans[i]); return 0; }
相关文章推荐
- [BZOJ4449][Neerc2015][分治][最短路]Distance on Triangulation
- [NEERC 2015] bzoj4449 Distance on Triangulation [分治+最短路]
- 【BZOJ 4449】[Neerc2015]Distance on Triangulation 多边形分治结构
- BZOJ4449 : [Neerc2015]Distance on Triangulation
- BZOJ4449: [Neerc2015]Distance on Triangulation
- 【bzoj 4449】[Neerc2015]Distance on Triangulation
- bzoj 4449: [Neerc2015]Distance on Triangulation
- [仙人掌 并查集 组合计数] BZOJ 4450 [Neerc2015]Cactus Jubilee
- codechef Prime Distance On Tree(树分治+FFT)
- Codechef Prime Distance On Tree(点分治+FFT)
- [BZOJ]4404: [Neerc2015]Binary vs Decimal
- bzoj4430 [Nwerc2015]Guessing Camels赌骆驼(CDQ分治)
- [BZOJ3924][ZJOI2015]幻想乡战略游戏(动态点分治)
- [ZJOI2015][bzoj3924] 幻想乡战略游戏 [动态点分治]
- bzoj4395【Usaco2015 Dec】Switching on the Lights
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
- [BZOJ4430][Nwerc2015]Guessing Camels赌骆驼(cdq分治)
- [BZOJ3939][Usaco2015 Feb]Cow Hopscotch(cdq分治)
- bzoj 4404 [Neerc2015]Binary vs Decimal题解
- 【BZOJ3924】【Zjoi2015】幻想乡战略游戏(树链剖分+点分治)