タイトル説明
ハムスターと彼のグループ(メイ)友達(ZI)砂糖ライブ地下の洞窟には、各ノードの数は、1〜nのです。地下洞窟は、ツリー構造です。この日の(a)からレストランの彼の寝室から小さなハムスター意思(B)、および彼の寝室の中に(C)からの彼のゲイの友人上のライブラリ(D)へ。彼らは、最短経路がかかります。今、小さなハムスターが知りたい、それはどこか、彼に基づいて、友人に会う可能ですか?
小さなハムスター弱いので、だけでなく、毎日が子zzq叔父である、あなたは彼を救う来てくださいます!
解決
もちろん、木が交差していてもよいです。
当初は、長いパスを判断するための基準として使用していたが、常にWAは、間違ったデータの下に小さな二つのうちの一つが、それはまた、非常に形而上学的で、尋ねることがわかりました。。。
だからではなく、基礎として研究・ポイントが判断する方法の。
チェーンのためのそのような木は、その両端点\(A、B \) 、以下に示すように。
私たちは別のポイントになるように、ツリー1ポイントのパスを構築したい場合は他の方法でラウンドでは、パスは彼らを助けるために起こって、既存のパスと交差しますか?
まず第一に、これは確かにそれの元の木の鎖に接続されているパスの最初の部分で、交差することは不可能です。
パスの残りは唯一の3例かもしれ構築します。
そして、このように構成されている場合、パスは、ツリーの定義に違反します。
私たちは、ことがわかっ構築パスは、元の木の鎖上の点がなければなりません。しかし、これは、我々はこの点を見つける方法がわからない、まだ悪いスタートです。
さらに別の観察、それが元のツリー鎖における新しいパスの特定のエンドポイントLCAが見出されました。LCAを見つけるのは簡単ですが、どのようにどのように需要の要件が大好きです。
だから、元の問題のために、私たちは、LCAは、チェーンツリー・ツー・ポイントの表現に他を指すようにするかどうかを判断するだけで済みます。
かどうかを決定木の上の点の点があれば簡単にチェーン、\(X \) 、我々はそれがあるかどうかを判断しなければならない(A、B \)\ツリーチェーンの
\((B)\ ) 、見かけの場合
深い\ [[X]> =深い[LCA(B)] \&\&(LCA(X)== X \ | LCA(B、 X)== X)\]
次に、真である(Xの\)\で\((B)\ ) で。
参照コード
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 100010
#define MOD 2520
#define E 1e-12
using namespace std;
inline int read()
{
int f=1,x=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct rec{
int next,ver;
}g[N<<1];
int head[N],tot;
inline void add(int x,int y)
{
g[++tot].ver=y;
g[tot].next=head[x],head[x]=tot;
}
int f[21][N],dep[N],n,t;
inline void init()
{
queue<int> q;
q.push(1);dep[1]=1;
while(q.size()){
int x=q.front();q.pop();
for(int i=head[x];i;i=g[i].next){
int y=g[i].ver;
if(dep[y]) continue;
f[0][y]=x;dep[y]=dep[x]+1;
for(int j=1;j<=t;++j)
f[j][y]=f[j-1][f[j-1][y]];
q.push(y);
}
}
}
inline int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int j=t;j>=0;--j)
if(dep[f[j][x]]>=dep[y]) x=f[j][x];
if(x==y) return x;
for(int j=t;j>=0;--j)
if(f[j][x]!=f[j][y]) x=f[j][x],y=f[j][y];
return f[0][x];
}
int main()
{
int q;
n=read(),q=read();t=log2(n)+1;
for(int i=1;i<n;++i){
int u=read(),v=read();
add(u,v),add(v,u);
}
init();
while(q--){
int a=read(),b=read(),c=read(),d=read();
int k1=lca(a,b),k2=lca(c,d);
if(dep[k1]>=dep[k2]&&(lca(c,k1)==k1||lca(d,k1)==k1)) puts("Y");
else if(dep[k2]>=dep[k1]&&(lca(a,k2)==k2||lca(b,k2)==k2)) puts("Y");
else puts("N");
}
return 0;
}