【GDKOI2011】反恐任务

#include <cstdio>
#include <iostream>
#define LL long long
#define RE register
#define IN inline
using namespace std;
const int N = 5e5 + 5;
int h[N << 1],h1[N],tot,tot1,stk[N],dfn[N << 1],low[N],cnt,dep[N << 1],s[N << 1],f[N << 1][21],n,m,Q,siz,top;

struct edge{
	int to,nxt;
}e[N << 2],e1[N << 1];
void add1(int x,int y)
{
	e1[++tot1] = edge{y,h1[x]},h1[x] = tot1;
	e1[++tot1] = edge{x,h1[y]},h1[y] = tot1;
}
void add(int x,int y)
{
	e[++tot] = edge{y,h[x]},h[x] = tot;
	e[++tot] = edge{x,h[y]},h[y] = tot;
}
IN void tarjan(int u)
{
	dfn[u] = low[u] = ++siz;
	stk[++top] = u;
	for (int i = h1[u]; i; i = e1[i].nxt)
	{
		int v = e1[i].to;
		if (!dfn[v]) 
		{
			tarjan(v),low[u] = min(low[u],low[v]);
			if (low[v] == dfn[u])
			{
				cnt++,add(cnt,u);
				for (int x = 0; x != v; top--) x = stk[top],add(cnt,x); 
			}
		}
		else low[u] = min(low[u],dfn[v]); 
	}
}
IN void dfs(int u,int fa)
{
	f[u][0] = fa,dfn[u] = ++siz,s[u] = 1,dep[u] = dep[fa] + 1;
	for (int i = 1; i <= 20; i++)
		if (f[u][i - 1]) f[u][i] = f[f[u][i - 1]][i - 1];
		else break;
	for (int i = h[u]; i; i = e[i].nxt)
		if (e[i].to != fa) dfs(e[i].to,u),s[u] += s[e[i].to];
}
IN int lca(int x,int y)
{
	if (dep[x] > dep[y]) swap(x,y);
	int tmp = dep[y] - dep[x];
	for (int i = 0; tmp; tmp >>= 1,i++)
		if (tmp & 1) y = f[y][i];
	if (x == y) return x;
	for (int i = 20; i >= 0; i--)
		if (f[x][i] != f[y][i]) x = f[x][i],y = f[y][i];
	return f[x][0]; 
}
int main() 
{
	scanf("%d%d",&n,&m);
	for (RE int i = 1,q,p; i <= m; i++) scanf("%d%d",&q,&p),add1(q,p);
	cnt = n,tarjan(1),scanf("%d",&Q),siz = 0,dfs(1,0);
	for (int ch,x,y,q,p; Q; Q--)
	{
		scanf("%d%d%d%d",&ch,&x,&y,&q);
		int t = lca(x,y);
		if (ch == 1)
		{
			scanf("%d",&p);
			if (dep[q] < dep[p]) swap(q,p);
			int k = f[q][0];
			if (s[k] > s[q] + 1) printf("yes\n");
			else if (dfn[q] <= dfn[t] && dfn[t] < dfn[q] + s[q]) printf("yes\n");
				else if ((dfn[q] <= dfn[x] && dfn[x] < dfn[q] + s[q]) || (dfn[q] <= dfn[y] && dfn[y] < dfn[q] + s[q])) printf("no\n");
					else printf("yes\n");
		}
		else
		{
			if (t == q) printf("no\n");
			else if (dfn[q] < dfn[t] && dfn[t] < dfn[q] + s[q]) printf("yes\n");
				else if ((dfn[q] <= dfn[x] && dfn[x] < dfn[q] + s[q]) || (dfn[q] <= dfn[y] && dfn[y] < dfn[q] + s[q])) printf("no\n");
					else printf("yes\n");
		}
	}
}
posted @ 2022-01-24 16:15  RiverSheep  阅读(64)  评论(0)    收藏  举报