对于删点
a
的操作有三种情况
- S,T都在
dfna
外
true
-
S,T
都在
dfna
中 我们把
S,T
沿着树走到
a
下,如果点一样或者都可以跳出去 true
-
S,T
其一在
dfna
把它沿着树走到
a
下如果可以跳出去true
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=5e5+5,S=18;
int h[M*2],g[M*2],nx[M*2],tot;
void Add(){
int x,y;scanf("%d %d",&x,&y);
g[++tot]=y,nx[tot]=h[x],h[x]=tot;
g[++tot]=x,nx[tot]=h[y],h[y]=tot;
}
void Min(int &a,int b){if(a>b)a=b;}
int Dfn,dfn[N],low[N],R[N],T[N],dep[N],fa[N][S],Tcnt;
int n,m,cmd;
void dfs(int x,int c){
T[x]=c;dfn[x]=low[x]=++Dfn;
for(int i=h[x];i;i=nx[i]){
int to=g[i];
if(to==fa[x][0])continue;
if(!dfn[to]){
fa[to][0]=x,dep[to]=dep[x]+1;
dfs(to,c);
low[x]=min(low[x],low[to]);
}else low[x]=min(low[x],dfn[to]);
}R[x]=Dfn;
}
int Up(int x,int p){
for(int i=0;i<S;i++)
if(p&(1<<i))x=fa[x][i];
return x;
}
void upto(int &x,int y){
int s=dep[x]-dep[y]-1;
if(s<=0)return;
for(int i=0;i<S;i++)
if(s&(1<<i))x=fa[x][i];
}
void Init(){
for(int i=0;i<S-1;i++)
for(int j=1;j<=n;j++)
fa[j][i+1]=fa[fa[j][i]][i];
}
bool In(int s,int f){
return dfn[f]<=dfn[s]&&dfn[s]<=R[f];
}
bool Cmd1(){
int a,b,x,y;
scanf("%d %d %d %d",&a,&b,&x,&y);
if(T[a]!=T[b])return 0;
if(T[a]!=T[y])return 1;
if(dep[x]>dep[y])swap(x,y);
if(fa[y][0]!=x)return 1;
if((In(a,y)&&In(b,y))||(!In(a,y)&&!In(b,y)))return 1;
if(low[y]<dfn[y])return 1;
return 0;
}
bool Cmd2(){
int a,b,x;
scanf("%d %d %d",&a,&b,&x);
if(T[a]!=T[b])return 0;
if(T[x]!=T[a])return 1;
if(!In(a,x)&&!In(b,x))return 1;
if(In(a,x)&&In(b,x)){
upto(a,x),upto(b,x);
if(a==b||(low[a]<dfn[x]&&low[b]<dfn[x]))return 1;
return 0;
}
if(In(a,x)){
upto(a,x);
return low[a]<dfn[x];
}else{
upto(b,x);
return low[b]<dfn[x];
}
}
int main(){
scanf("%d %d",&n,&m);
while(m--)Add();
for(int i=1;i<=n;i++)
if(!dfn[i])dfs(i,++Tcnt);
Init();
scanf("%d",&m);
while(m--){
scanf("%d",&cmd);
if(cmd==1)puts(Cmd1()?"yes":"no");
else puts(Cmd2()?"yes":"no");
}
return 0;
}