给一棵树,三个点,问其中两个点到第三个点的公共路径长度最大值是多少。
三个点两两求一下LCA,肯定会有两个LCA相同。然后再分一下情况求距离即可。
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN=400100;
const int mod=1e9+7;
struct edge{
int to,next;
}e[MAXN<<1];
int head[MAXN];
int tot=0;
void add(int u,int v){
e[tot].to=v;
e[tot].next=head[u];
head[u]=tot++;
}
int dep[MAXN];
int fir[MAXN];
int que[MAXN<<1];
int p[MAXN];
int st[MAXN][20];
int vis[MAXN];
int cnt=0;
void dfs(int u,int d){
vis[u]=1;
que[++cnt]=u;fir[u]=cnt;dep[cnt]=d;
for(int k=head[u];k!=-1;k=e[k].next){
int v=e[k].to;
if(!vis[v]){
p[v]=u;
dfs(v,d+1);
que[++cnt]=u;dep[cnt]=d;
}
}
}
void ST(int n){
for(int i=1;i<=n;i++)
st[i][0]=i;
for(int j=1;(1<<j)<=n;j++){
for(int i=1;i+(1<<j)-1<=n;i++){
int a=st[i][j-1],b=st[i+(1<<(j-1))][j-1];
st[i][j]=dep[a]<dep[b]?a:b;
}
}
}
int RMQ(int l,int r){
int k=0;
while((1<<(k+1))<=r-l+1){
k++;
}
int a=st[l][k],b=st[r-(1<<k)+1][k];
return dep[a]<dep[b]?a:b;
}
int lca(int u,int v){
int x=fir[u],y=fir[v];
if(x>y)
swap(x,y);
int res=RMQ(x,y);
return que[res];
}
struct path{
int u,v;
int lca;
}pa[MAXN];
int cmp(path x,path y){
return dep[fir[x.lca]]>dep[fir[y.lca]];
}
int used[MAXN];
void init(){
tot=0;
cnt=0;
p[1]=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(used,0,sizeof(used));
}
int depth(int u){
return -dep[fir[u]];
}
int L[3];
int main(){
int n,q;
while(scanf("%d%d",&n,&q)!=EOF){
init();
for(int i=2;i<=n;i++){
int u;
scanf("%d",&u);
add(i,u);
add(u,i);
}
dfs(1,1);
ST(2*n-1);
for(int i=0;i<q;i++){
int a,b,c;
int res=0;
scanf("%d%d%d",&a,&b,&c);
L[0]=lca(a,b);
L[1]=lca(a,c);
L[2]=lca(b,c);
if(L[0]==L[1]&&L[0]==L[2]){
res=max(res,depth(L[0])-depth(a));
res=max(res,depth(L[0])-depth(b));
res=max(res,depth(L[0])-depth(c));
}else{
if(L[1]==L[2]){
swap(a,c);
swap(L[0],L[2]);
}else if(L[0]==L[2]){
swap(a,b);
swap(L[1],L[2]);
}
res=max(res,2*depth(L[0])-depth(a)-depth(L[2]));
if(L[2]==b){
res=max(res,depth(b)-depth(c));
}else if(L[2]==c){
res=max(res,depth(c)-depth(b));
}else
res=max(res,max(depth(L[2])-depth(b),depth(L[2])-depth(c)));
}
printf("%d\n",res+1);
}
}
}