标签:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int M = 200005;
struct Edge{
int v, next;
} edge[M << 1];
int E; int head[M];
void add_edge(int s, int v){
edge[E].next = head[s];
edge[E].v = v;
head[s] = E ++;
}
int fa[M][23];
int deep[M];
int vis[M];
int sum[M];
void bfs(){
queue<int> q;
q.push(1);
memset(vis, 0, sizeof(vis));
memset(sum, 0, sizeof(sum));
fa[1][0] = 1;
deep[1] = 0;
vis[1] = 1;
sum[1] = 1;
while(!q.empty()){
int u = q.front(); q.pop();
for(int j = 1; j <= 20; j ++) {
fa[u][j] = fa[fa[u][j-1]][j-1];
}
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].v;
if(vis[v]) continue;
sum[v] = sum[u] + 1;
vis[v] = 1;
fa[v][0] = u;
deep[v] = deep[u] + 1;
q.push(v);
}
}
}
int lca(int a, int b){
if(deep[a] > deep[b]) swap(a, b);
int ta = a; int tb = b;
int da = deep[a]; int db = deep[b];
for(int i = 0, dd = db - da; dd; dd >>= 1, i ++){
if(dd&1)
tb = fa[tb][i];
}
if(tb == ta) return tb;
for(int i = 20; i >= 0; i --){
if(fa[ta][i] == fa[tb][i]) continue;
ta = fa[ta][i];
tb = fa[tb][i];
}
return fa[ta][0];
}
int main(){
int n, m;
scanf("%d%d", &n, &m);
int a, b;
memset(head, -1, sizeof(head));
for(int i = 2; i <= n; i ++){
scanf("%d", &a);
add_edge(a, i);
add_edge(i, a);
}
bfs();
while(m --){
scanf("%d%d", &a, &b);
int lc = lca(a, b);
if(deep[lc] == deep[a])
printf("%d %d\n", sum[lc], sum[b] - sum[lc]);
else if(deep[lc] == deep[b]){
printf("%d %d\n", sum[a] - sum[lc], sum[lc]);
}else {
printf("%d %d\n", sum[a], sum[b] - sum[lc]);
}
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/acmood/p/4537641.html