tt是哪个图,t是该树在环上点。
码风简洁好康,麻烦各位神仙看一下,实在不知道哪里错了= =。
还有为啥我的最后 x, y 全部要减一,但是题解不需要?
可以有偿
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 1000010;
const int MAXM = 100010;
const int MAXINT = 2147483647;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int n, m, k;
int ans, tot, res;
int a[MAXN];
int head[MAXN], dep[MAXN], f[MAXN][50], cnt[MAXN];
int t[MAXN], tt[MAXN], vis[MAXN], lg[MAXN], id[MAXN];
vector<int> cir[MAXN];
string s;
inline int read() {
int s = 0, f = 1;
char ch = getchar();
while ('0' > ch || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
while ('0' <= ch && ch <= '9') {s = (s << 3) + (s << 1) + ch - 48; ch = getchar();}
return s * f;
}
struct edge {
int to, next;
}e[MAXN * 2];
void add_edge(int x, int y) {
e[++tot].to = y;
e[tot].next = head[x];
head[x] = tot;
return;
}
int Get_Circle(int k, int x, int fa) {
if (vis[x]) return x;
else vis[x] = -1;
for (int i = head[x]; i; i = e[i].next) {
int y = e[i].to;
if (y == fa) continue;
res = Get_Circle(k, y, x);
if (res) {
cir[k].push_back(0);
cir[k][++cnt[k]] = x;
id[x] = cnt[k];
vis[x] = 1;
return res == x ? 0 : res;
}
}
return 0;
}
void dfs(int x, int fa) {
tt[x] = !fa ? x : tt[fa];
f[x][0] = fa;
dep[x] = dep[fa] + 1;
for (int i = 1; (1 << i) <= dep[x]; i++) {
f[x][i] = f[f[x][i - 1]][i - 1];
}
for (int i = head[x]; i; i = e[i].next) {
int y = e[i].to;
if (y == fa || vis[y] == 1) continue;
dfs(y, x);
}
return;
}
int Lca(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);
while (dep[x] > dep[y]) {
x = f[x][lg[dep[x] - dep[y]] - 1];
}
if (x == y) return x;
for (int i = lg[dep[x]]; i >= 0; i--) {
if (f[x][i] != f[y][i]) {
x = f[x][i];
y = f[y][i];
}
}
return f[x][0];
}
int find(int x) {
while (x != t[x]) x = t[x] = t[t[x]];
return x;
}
bool pd(int x1, int y1, int x2, int y2) {
if(max(x1,y1) != max(x2,y2)) return max(x1, y1) < max(x2, y2);
if(min(x1,y1) != min(x2,y2)) return min(x1, y1) < min(x2, y2);
return x1 >= y1;
}
int main(){
int q;
scanf("%d%d", &n, &q);
for (int i = 1; i <= n; i++) {
t[i] = i;
lg[i] = lg[i - 1] + ((1 << lg[i - 1]) == i);
}
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
add_edge(a[i], i);
t[i] = t[a[i]];
}
for (int i = 1; i <= n; i++) {
int fd = find(t[i]);
if (cnt[fd]) continue;
cir[fd].push_back(0);
Get_Circle(fd, i, 0);
for (int j = 1; j <= cnt[fd]; j++) {
dfs(cir[fd][j], 0);
}
}
for (int i = 1, x, y; i <= q; i++) {
scanf("%d%d", &x, &y);
int fx = find(t[x]);
int fy = find(t[y]);
if (find(fx) != find(fy)) {
puts("-1 -1");
continue;
}
if (tt[x] == tt[y]) {
int l = Lca(x, y);
printf("%d %d\n", dep[x] - dep[l], dep[y] - dep[l]);
continue;
}
int d1 = dep[x] + (id[tt[y]] - id[tt[x]] + cnt[fx]) % cnt[fx], d2 = dep[y] + (id[tt[x]] - id[tt[y]] + cnt[fx]) % cnt[fx];
if (pd(dep[x], d2, d1, dep[y])) printf("%d %d\n", dep[x] - 1, d2 - 1);
else printf("%d %d\n", d1 - 1, dep[y] - 1);
}
return 0;
}