我居然把swap写成了switch
如果路径相交,那么一定有LCA(a,b)在路径c,d上,或LCA(c,d)在路径a,b上
如果x在路径a,b上,需要满足条件:
dpth[x] >= dpth[LCA(a,b)]
LCA(a,x)=x 或 LCA(b,x)=x
就这样,求出LCA后分别判断一下即可
代码如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #define MogeKo qwq using namespace std; const int maxn = 2e5+10; int n,q,x,y,a,b,c,d,e,f,cnt; int dpth[maxn],p[maxn][25]; int head[maxn],to[maxn],nxt[maxn]; void add(int x,int y) { to[++cnt] = y; nxt[cnt] = head[x]; head[x] = cnt; } void dfs(int x,int fa) { dpth[x] = dpth[fa]+1; p[x][0] = fa; for(int i = 1; (1<<i) <= dpth[x]; i++) p[x][i] = p[p[x][i-1]][i-1]; for(int i = head[x]; i; i = nxt[i]) { if(dpth[to[i]]) continue; if(to[i] == fa) continue; dfs(to[i],x); } } int lca(int a,int b) { if(dpth[a] < dpth[b]) swap(a,b); for(int i = 20; i >= 0; i--) if(dpth[a] - (1<<i) >= dpth[b]) a = p[a][i]; if(a == b) return a; for(int i = 20; i >= 0; i--) if(p[a][i] != p[b][i]) a = p[a][i],b = p[b][i]; return p[a][0]; } bool check(int a,int b,int c,int d) { if(dpth[d] >= dpth[c]) if(lca(a,d)==d || lca(b,d)==d) return true; return false; } int main() { scanf("%d%d",&n,&q); for(int i = 1; i <= n-1; i++) { scanf("%d%d",&x,&y); add(x,y),add(y,x); } dfs(1,-1); while(q--) { scanf("%d%d%d%d",&a,&b,&c,&d); e = lca(a,b); f = lca(c,d); if(check(a,b,e,f) || check(c,d,f,e)) printf("Y "); else printf("N "); } return 0; }