1-Trees and Queries
该题需要用 lca 进行优化。
在树中求两点间的距离的方法为:dis=dep[l]+dep[r]-2*dep[lca(l,r)]
// Created by CAD on 2020/2/16.
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n;
//-----------------前向星--------------------
int cnt=0,head[maxn<<1];
struct edge{
int to,w,next;
}e[maxn<<1];
void add(int u,int v,int w){
e[++cnt]=edge{v,w,head[u]};
head[u]=cnt;
}
//--------------------树链剖分----------------------
int dep[maxn],id[maxn],siz[maxn],son[maxn],f[maxn],top[maxn],w[maxn];
int tot;
void dfs1(int x,int fa,int deep){
dep[x]=deep,f[x]=fa,siz[x]=1;
int maxson=-1;
for(int i=head[x];i;i=e[i].next){
int v=e[i].to;
if(v==fa) continue;
w[v]=e[i].w;
dfs1(v,x,deep+1);
siz[x]+=siz[v];
if(siz[v]>maxson) maxson=siz[v],son[x]=v;
}
}
void dfs2(int x,int from){
id[x]=++tot;
top[x]=from;
if(son[x]) dfs2(son[x],from);
for(int i=head[x];i;i=e[i].next){
int v=e[i].to;
if(v==son[x]||v==f[x]) continue;
dfs2(v,v);
}
}
int qrange(int l,int r){
int ans=dep[l]+dep[r];
while(top[l]!=top[r]){
if(dep[top[l]]<dep[top[r]]) swap(l,r);
l=f[top[l]];
}
if(dep[l]>dep[r]) swap(l,r);
ans-=(2*dep[l]);
return ans;
}
int main()
{
scanf("%d", &n);
for (int i=1; i<=n-1; ++i)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v, 1), add(v, u, 1);
}
w[1]=1;
dfs1(1, 0, 1), dfs2(1, 1);
int q; scanf("%d", &q);
while (q--)
{
int x, y, a, b, k;
scanf("%d%d%d%d%d", &x, &y, &a, &b, &k);
int ab=qrange(a, b);
bool ok=0;
if (ab<=k && ab%2==k%2) ok=1;
else
{
int ax=qrange(a, x), ay=qrange(a, y), xb=qrange(x, b), yb=qrange(y, b);
int r1=ax+yb+1, r2=ay+xb+1;
if (r1<=k && r1%2==k%2) ok=1;
if (r2<=k && r2%2==k%2) ok=1;
}
puts(ok ? "YES" : "NO");
}
return 0;
}
CAD加油!欢迎跟我一起讨论学习算法,QQ:1401650042