一开始理解错题意,以为他俩速度一样,同时出发,结果发现样例也过不了。手玩一下样例,发现好像只要路径相交就行了如果路径有相交,说明有个LCA在另一条路径上,否则就有环了。然后树剖求个LCA。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=100005;
int n,q,head[N],ecnt,siz[N],fa[N],dep[N],top[N],son[N];
int rd() {
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
struct Edge{int to,nxt;}e[N<<1];
void add(int bg,int ed){e[++ecnt].to=ed;e[ecnt].nxt=head[bg];head[bg]=ecnt;swap(bg,ed);e[++ecnt].to=ed;e[ecnt].nxt=head[bg];head[bg]=ecnt;}
void dfs(int x) {
siz[x]=1;
for(int i=head[x];i;i=e[i].nxt) {
if(e[i].to==fa[x]) continue;
int v=e[i].to;dep[v]=dep[x]+1;fa[v]=x;dfs(v);siz[x]+=siz[v];
son[x]=siz[v]>siz[son[x]]?v:son[x];
}
}
void dfs(int x,int qtop) {
top[x]=qtop;
if(!son[x]) return;
dfs(son[x],qtop);
for(int i=head[x];i;i=e[i].nxt) {
int v=e[i].to;
if(v==fa[x]||v==son[x]) continue;
dfs(v,v);
}
}
int lca(int x,int y) {
while(top[x]!=top[y])
(dep[top[x]]>=dep[top[y]])?x=fa[top[x]]:y=fa[top[y]];
return dep[x]<dep[y]?x:y;
}
int main() {
n=rd(),q=rd();
for(int i=1;i<n;i++)add(rd(),rd());
dfs(1);dfs(1,1);
int a,b,c,d,lcaa,lcab;
while(q--) {
a=rd(),b=rd(),c=rd(),d=rd();
lcaa=lca(a,b),lcab=lca(c,d);
if(dep[lcaa]<dep[lcab]) {
swap(lcaa,lcab),swap(a,c),swap(b,d);
}
if(lca(lcaa,c)==lcaa||lca(lcaa,d)==lcaa) puts("Y");
else puts("N");
}
}