bzoj 2791 [Poi2012]Rendezvous 倍增lca 基环树
来源:互联网 发布:知乎恐怖提问 编辑:程序博客网 时间:2024/06/08 04:52
这是一个基环内向树森林。两个点如果在一个子树中,直接倍增lca。
否则两个点先走到环上,然后一个点不动,另一个点走到这个点。
#include <bits/stdc++.h>using namespace std;#define N 510000int n,q,top,cnt;int fa[N][21];int vis[N],st[N],inc[N],root[N],deep[N];int bel[N],ins[N],num[N],sum[N];void dfs(int x){ st[++top]=x;vis[x]=ins[x]=1; int y=fa[x][0]; if(ins[y]) { int t=0; bel[y]=++cnt;inc[y]=1;num[y]=t; fa[y][0]=0;root[y]=y; for(int i=top;st[i]!=y;i--) { inc[st[i]]=1,bel[st[i]]=cnt; root[st[i]]=st[i];num[st[i]]=++t; fa[st[i]][0]=0; } sum[cnt]=t+1;ins[x]=0; return; } if(!vis[y])dfs(y); ins[x]=0; if(inc[x])return; bel[x]=bel[y];deep[x]=deep[y]+1; root[x]=root[y]; for(int i=1;i<=20;i++) fa[x][i]=fa[fa[x][i-1]][i-1];}int lca(int x,int y){ if(deep[x]<deep[y])swap(x,y); for(int i=20;i>=0;i--) if(deep[fa[x][i]]>=deep[y]) x=fa[x][i]; if(x==y)return x; for(int i=20;i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; return fa[x][0];}int main(){ scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) scanf("%d",&fa[i][0]); for(int i=1;i<=n;i++) if(!vis[i]){top=0;dfs(i);} for(int a,b,x,y;q--;) { scanf("%d%d",&a,&b); if(bel[a]!=bel[b]) {puts("-1 -1");continue;} if(root[a]==root[b]) { int t=lca(a,b); x=deep[a]-deep[t],y=deep[b]-deep[t]; printf("%d %d\n",x,y); } else { x=deep[a];y=deep[b]; a=root[a];b=root[b]; int m=sum[bel[a]]; int x1=x+(num[a]-num[b]+m)%m,y1=y; int x2=x,y2=y+(num[b]-num[a]+m)%m; int mx1=max(x1,y1),mx2=max(x2,y2),mn1=min(x1,y1),mn2=min(x2,y2); if(mx1<mx2||(mx1==mx2&&mn1<mn2)||(mx1==mx2&&mn1==mn2&&x1>=y1)) printf("%d %d\n",x1,y1); else printf("%d %d\n",x2,y2); } } return 0;}
0 0
- bzoj 2791 [Poi2012]Rendezvous 倍增lca 基环树
- BZOJ 2791 Poi2012 Rendezvous 倍增LCA
- [BZOJ 2791]POI2012 Rendezvous
- [POI 2012]Rendezvous(倍增LCA)
- BZOJ2791: [Poi2012]Rendezvous
- BZOJ2791/POI2012 Rendezvous
- BZOJ2791: [Poi2012]Rendezvous
- BZOJ 3732 Network Kruskal+倍增LCA
- BZOJ 1787 AHOI2008 紧急集合 倍增LCA
- 【BZOJ 1832】 [AHOI2008]聚会|倍增lca
- BZOJ 4144 Dijkstra+Kruskal+倍增LCA
- 倍增LCA(bzoj 3732: Network)
- BZOJ 3712 Fiolki (倍增LCA)
- bzoj 2144: 跳跳棋 lca+倍增
- lca倍增
- lca(倍增)
- 倍增LCA
- 倍增lca
- 菜单展开问题
- 兼容性问题<meta http-equiv="X-UA-Compatible" content="IE=edge">
- centos安装pptp、vpn
- HDFS基本命令
- Android设置之UI篇
- bzoj 2791 [Poi2012]Rendezvous 倍增lca 基环树
- Discarding record on action DISCARD on error 1403
- json数据表单回填
- VB里面的Line方法的具体使用方法
- DevExpress ComboBoxEdit List绑定二级选择下拉表
- Android源码中的组合模式
- LeetCode No.120 Triangle
- Uiautomator之python封装包安装
- 一步一步用 java 设计生成二维码