题目大意
在一棵树上面,给出两条路径,判断是否有交集。
题解
利用路径的lca还有是否在子树里面就可简单的判断。
code
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#define N 100003
#define M 103
#define P putchar
#define G getchar
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
int w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
n*=w;
}
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
int abs(int x){return x<0?-x:x;}
void write(int x){if(x>9) write(x/10);P(x%10+'0');}
int n,m,x,y,f[17][N],dep[N],xx,yy;
int nxt[N*2],to[N*2],lst[N],tot,lca1,lca2;
void ins(int x,int y)
{
nxt[++tot]=lst[x];
to[tot]=y;
lst[x]=tot;
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
for(int i=16;i+1;i--)
if(dep[f[i][x]]>=dep[y])x=f[i][x];
if(x==y)return x;
for(int i=16;i+1;i--)
if(f[i][x]^f[i][y])x=f[i][x],y=f[i][y];
return f[0][x];
}
void dfs(int x)
{
for(int i=lst[x];i;i=nxt[i])
if(to[i]^f[0][x])f[0][to[i]]=x,dep[to[i]]=dep[x]+1,dfs(to[i]);
}
bool pd(int pos,int len)
{
if(lca(lca1,pos)^lca1)return 0;
if(dep[pos]-dep[lca(pos,x)]<=len)return 1;
if(dep[pos]-dep[lca(pos,y)]<=len)return 1;
return 0;
}
int main()
{
freopen("inter.in","r",stdin);
freopen("inter.out","w",stdout);
read(n);
for(int i=1;i<n;i++)
read(x),read(y),ins(x,y),ins(y,x);
dfs(dep[1]=1);
for(int j=1;j<=16;j++)
for(int i=1;i<=n;i++)
f[j][i]=f[j-1][f[j-1][i]];
for(read(m);m;m--)
{
read(x);read(y);read(xx);read(yy);
lca1=lca(x,y);lca2=lca(xx,yy);
if(pd(xx,dep[xx]-dep[lca2]) || pd(yy,dep[yy]-dep[lca2]))P('Y'),P('E'),P('S');
else P('N'),P('O');
P('\n');
}
return 0;
}