显示代码纯文本
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 500010;
int n, m, inc[MAXN], stp[MAXN], num[MAXN], len[MAXN], dep[MAXN], f[20][MAXN], bel[MAXN], cnt;
vector<int> cd[MAXN];
void dfs(int x, int fa, int rt, int d) {
bel[x] = rt;
dep[x] = d;
for(int i = 0; i < cd[x].size(); i ++) {
int u = cd[x][i];
if(inc[u] || u == fa) {
continue;
}
// dep[u] = dep[x] + 1;
dfs(u, x, rt, d + 1);
}
}
int lca(int x, int y) {
if(dep[x] < dep[y]) {
swap(x, y);
}
for(int i = 20; i >= 0; i --) {
int u = f[i][x];
if(dep[u] >= dep[y]) {
x = u;
}
}
if(x == y) {
return x;
}
for(int i = 20; i >= 0; i --) {
int u = f[i][x], v = f[i][y];
if(u != v) {
x = u;
y = v;
}
}
return f[0][x];
}
void find_circle(int x, int id, int s) {
if(stp[x]) {
return ;
}
num[x] = id;
len[id] ++;
stp[x] = s;
find_circle(f[0][x], id, s + 1);
}
int 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() {
freopen("rdz.in", "r", stdin);
freopen("rdz.out", "w", stdout);
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++) {
int x;
scanf("%d", &x);
f[0][i] = x;
cd[x].push_back(i);
inc[x] ++;
}
queue<int> q;
for(int i = 1; i <= n; i ++) {
if(!inc[i]) {
q.push(i);
}
}
while(!q.empty()) {
int x = q.front();
q.pop();
int u = f[0][x];
inc[u] --;
if(!inc[u]) {
q.push(u);
}
}
for(int i = 1; i <= 20; i ++) {
for(int j = 1; j <= n; j ++) {
f[i][j] = f[i - 1][f[i - 1][j]];
}
}
for(int i = 1; i <= n; i ++) {
if(inc[i]) {
dfs(i, 0, i, 0);
if(!stp[i]) {
find_circle(i, ++ cnt, 1);
}
}
}
for(int i = 1; i <= m; i ++) {
int x, y;
scanf("%d%d", &x, &y);
// cout << " ";
// cout << " ";
if(num[bel[x]] != num[bel[y]]) {
printf("-1 -1\n");
}
else if(bel[x] == bel[y]) {
int w = lca(x, y);
printf("%d %d\n", dep[x] - dep[w], dep[y] - dep[w]);
}
else {
// cout << 11111 << ' ';
int u = bel[x], v = bel[y];
int ans1 = dep[x] + (stp[v] - stp[u] + len[num[u]]) % len[num[u]];
int ans2 = dep[y] + (stp[u] - stp[v] + len[num[u]]) % len[num[u]];
// cout << ans1 << ' ' << ans2 << ' ';
if(check(dep[x], ans2, ans1, dep[y])) {
printf("%d %d\n", dep[x], ans2);
}
else {
printf("%d %d\n", ans1, dep[y]);
}
}
}
return 0;
}