题目大意
给出一个(N)个点的树,给出两条路径的起点和终点,问两条路径有没有交
问题求解
这道题貌似是一道比较模板的题目,至于为什么蓝我就不知道了,笑
我们可以求出起点和重点的(LCA),显然,如果两条路径相交的话,一个路径的(LCA)必定在另外一条路径上
然后判断一个点是否在一个路径上要满足两个条件
-
(deep[x]≥deep[LCA(s,t)])
-
(LCA(x,s)==x||LCA(x,t)==x)
就分两种情况判断一下就好了
代码实现
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5,maxe=2e5+5;
int N,Q;
int lnk[maxn],nxt[maxe],son[maxe],cnt;
int fa[maxn],size[maxn],top[maxn],dep[maxn];
inline int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline void add_e(int x,int y){son[++cnt]=y;nxt[cnt]=lnk[x];lnk[x]=cnt;}
void dfs1(int x){
size[x]=1;dep[x]=dep[fa[x]]+1;
for(int j=lnk[x];j;j=nxt[j]){
if(son[j]==fa[x])continue;
fa[son[j]]=x;dfs1(son[j]);size[x]+=size[son[j]];
}
return ;
}
void dfs2(int x){
int w=0;
if(!top[x])top[x]=x;
for(int j=lnk[x];j;j=nxt[j])if(son[j]!=fa[x]&&size[son[j]]>size[w])w=son[j];
if(w){top[w]=top[x];dfs2(w);}
for(int j=lnk[x];j;j=nxt[j])if(son[j]!=fa[x]&&son[j]!=w)dfs2(son[j]);
return ;
}
int lca(int x,int y){
for(;top[x]!=top[y];)dep[top[x]]<dep[top[y]]&&(swap(x,y),0),x=fa[top[x]];
dep[x]>dep[y]&&(swap(x,y),0);
return x;
}
int main(){
N=read();Q=read();
for(int i=1;i<N;i++){
int x=read(),y=read();
add_e(x,y);add_e(y,x);
}
dfs1(1);dfs2(1);
for(int i=1;i<=Q;i++){
int a=read(),b=read(),c=read(),d=read();
int a_b=lca(a,b),c_d=lca(c,d);
if(dep[a_b]<dep[c_d]){swap(a_b,c_d);swap(a,c);swap(b,d);}
if(lca(a_b,c)==a_b||lca(a_b,d)==a_b)printf("Y
");
else printf("N
");
}
return 0;
}