-
F - Misha, Grisha and Underground
- CodeForces - 832D
- 利用lca求出树上距离然后根据树上三点路径之间交点公式取其最大值即可
-
#include<bits/stdc++.h> using namespace std; #define maxn 200005 int n,q,tot,dep[maxn],p; int dp[maxn][20],a,b,c,k; int head[maxn]; struct node { int v,to; } edge[maxn*2]; void add(int u,int v) { edge[++tot].to=head[u]; edge[tot].v=v; head[u]=tot; edge[++tot].to=head[v]; edge[tot].v=u; head[v]=tot; } void dfs(int u,int pre) { dep[u]=dep[pre]+1; dp[u][0]=pre; for(int i=1; (1<<i)<=dep[u]; i++) dp[u][i]=dp[dp[u][i-1]][i-1]; for(int i=head[u]; i!=-1; i=edge[i].to) { int v=edge[i].v; if(v==pre)continue; dfs(v,u); } } int lca(int x,int y) { if(dep[x]<dep[y]) swap(x,y); for(int i=k; i>=0; i--) if(dep[x]-(1<<i)>=dep[y]) x=dp[x][i]; if(x==y) return x; for(int i=k; i>=0; i--) if(dp[x][i]!=dp[y][i]) { x=dp[x][i]; y=dp[y][i]; } return dp[x][0]; } void ans() { int x,y,z,s1,s2,s3,out=0; x=lca(a,b); y=lca(b,c); z=lca(a,c); s1=dep[a]+dep[b]-2*dep[x]; s2=dep[b]+dep[c]-2*dep[y]; s3=dep[a]+dep[c]-2*dep[z]; out=max(max(s1+s2-s3,s1+s3-s2),s2+s3-s1); printf("%d\n",out/2+1); } int main() { memset(head,-1,sizeof(head)); scanf("%d%d",&n,&q); for(int i=2; i<=n; i++) { scanf("%d",&p); add(i,p); } dfs(2,0); k=log(n)/log(2); while(q--) { scanf("%d%d%d",&a,&b,&c); ans(); } return 0; }
F - Misha, Grisha and Underground-LCA+路径
最新推荐文章于 2020-08-06 16:16:27 发布