1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| #include<bits/stdc++.h> const int MAXN=500010; using namespace std; int indeg[MAXN],n,m,wcc[MAXN],anc[MAXN][21],dep[MAXN],cirlen[MAXN],cirid[MAXN],cirpos[MAXN],tot; vector <int> g[MAXN]; queue <int> q; void dfs(int u,int f,int rt,int d) { dep[u]=d;wcc[u]=rt; for(int i=0;i<g[u].size();i++) { int v=g[u][i]; if(indeg[v]||v==f)continue; dfs(v,u,rt,d+1); } } void pre() { for(int p=1;p<=19;p++) for(int i=1;i<=n;i++) anc[i][p]=anc[anc[i][p-1]][p-1]; } int lca(int x,int y) { if(dep[x]<dep[y])swap(x,y); int tmp=dep[x]-dep[y]; for(int i=19;i>=0;i--)if(tmp>>i&1)x=anc[x][i]; if(x==y)return y; for(int i=19;i>=0;i--) { if(anc[x][i]!=anc[y][i])x=anc[x][i],y=anc[y][i]; } return anc[x][0]; } void circle(int u,int id,int az) { if(cirpos[u])return; cirid[u]=id;cirlen[id]++;cirpos[u]=az; circle(anc[u][0],id,az+1); } bool check(int a,int b,int c,int d) { if(max(a,b)!=max(c,d))return max(a,b)<max(c,d); if(min(a,b)!=min(c,d))return min(a,b)<min(c,d); return a>=b; } signed main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { int u;scanf("%d",&u); g[u].push_back(i); anc[i][0]=u; indeg[u]++; } for(int i=1;i<=n;i++)if(!indeg[i])q.push(i); while(!q.empty()) { int u=q.front();q.pop(); int v=anc[u][0]; indeg[v]--; if(!indeg[v])q.push(v); } for(int i=1;i<=n;i++) { if(indeg[i]) { dfs(i,0,i,0); if(!cirpos[i])circle(i,++tot,1); } } pre(); while(m--) { int u,v;scanf("%d%d",&u,&v); if(cirid[wcc[u]]!=cirid[wcc[v]]) { cout<<-1<<' '<<-1<<endl; } else if(wcc[u]==wcc[v]) { int LCA=lca(u,v); cout<<dep[u]-dep[LCA]<<' '<<dep[v]-dep[LCA]<<endl; } else { int t1=wcc[u],t2=wcc[v]; int ans1=dep[u]+(cirpos[t2]-cirpos[t1]+cirlen[cirid[t1]])%cirlen[cirid[t1]]; int ans2=dep[v]+(cirpos[t1]-cirpos[t2]+cirlen[cirid[t1]])%cirlen[cirid[t1]]; if(check(dep[u],ans2,ans1,dep[v]))cout<<dep[u]<<' '<<ans2<<endl; else cout<<ans1<<' '<<dep[v]<<endl; } } return 0; }
|