题意
有一棵树,多次询问,每次额外在树上加一条边x,y(这个不会带到下一次询问中),再问两个点a,b能否恰好走k条边到达,边可以反复走。
数据范围
解法
感觉非常结论。。。推了一下后发现从a走到b要么不走新边,要么从a走到x,要么从a走到y,看起来一共就3种情况,然后就对了
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
inline int read(){
char c=getchar();int t=0,f=1;
while((!isdigit(c))&&(c!=EOF)){if(c=='-')f=-1;c=getchar();}
while((isdigit(c))&&(c!=EOF)){t=(t<<3)+(t<<1)+(c^48);c=getchar();}
return t*f;
}
int n;
struct edge{
int v,p;
}e[maxn<<1];
int h[maxn],cnt;
inline void add(int a,int b){
e[++cnt].p=h[a];
e[cnt].v=b;
h[a]=cnt;
e[++cnt].p=h[b];
e[cnt].v=a;
h[b]=cnt;
}
int dep[maxn],fa[maxn][20];
void dfs(int u,int f){
fa[u][0]=f;dep[u]=dep[f]+1;
for(int i=1;fa[u][i-1];i++)fa[u][i]=fa[fa[u][i-1]][i-1];
for(int i=h[u];i;i=e[i].p){
int v=e[i].v;
if(v==f)continue;
dfs(v,u);
}
}
inline int lca(int a,int b){
if(dep[a]>dep[b])swap(a,b);
for(int j=19;j>=0;j--){
if(dep[a]<=dep[fa[b][j]]){b=fa[b][j];}
}
if(a==b)return a;
for(int j=19;j>=0;j--){
if(fa[a][j]!=fa[b][j]){
a=fa[a][j];
b=fa[b][j];
}
}
return fa[a][0];
}
int main(){
//freopen("5.in","r",stdin);
//freopen("5.out","w",stdout);
n=read();
for(int i=1;i<n;i++){
int u=read(),v=read();
add(u,v);
}
dfs(1,0);
int q=read();
while(q--){
int x=read(),y=read(),a=read(),b=read(),k=read();
int l=lca(a,b);
int dis=dep[a]+dep[b]-2*dep[l];
if(dis<=k&&((k-dis)%2==0)){puts("YES");continue;}
int a1=lca(a,x),a2=lca(a,y),b1=lca(b,x),b2=lca(b,y);
int dis1=dep[a]+dep[x]-2*dep[a1]+1+dep[y]+dep[b]-2*dep[b2],dis2=dep[a]+dep[y]-2*dep[a2]+1+dep[x]+dep[b]-2*dep[b1];
if(dis1<=k&&((k-dis1)%2==0)){puts("YES");continue;}
if(dis2<=k&&((k-dis2)%2==0)){puts("YES");continue;}
puts("NO");
}
return 0;
}