【P3398]】仓鼠找sugar

暴力lca


题目

有一种情况肯定不行

较深得lca深度比浅的两个点还深,直接不行

如果可能存在解

则解一定是介中情况

较深的lca一定在另一个lca路径上。

判读呢?

就是用深的lca和浅的lca的两个点做lca

做出来的lca是浅的lca。那就是在路径上了

#include<iostream>
#include<cstdio>
using namespace std;
struct node
{
	int point;
	int nxt;
};
node line[201000];
int head[101000],tail;
int dep[101000];
int st[101000][20];
int log[1010000];
void add(int x,int y)
{
	line[++tail].point=y;
	line[tail].nxt=head[x];
	head[x]=tail;
}
void dfs(int now,int fa) 
{
	dep[now]=dep[fa]+1;
	st[now][0]=fa;
	for(int i=1;i<=log[dep[now]];i++)
		st[now][i]=st[st[now][i-1]][i-1];
	int need=head[now];
	while(need!=-1)
	{
		if(line[need].point!=fa)
			dfs(line[need].point,now);
		need=line[need].nxt;
	}
}
int lca(int x,int y)
{
	if(dep[x]<dep[y]) 
		swap(x,y);
	for(int i=log[dep[x]];i>=0;i--)
		if(dep[st[x][i]]>=dep[y])
			x=st[x][i];
	if(x!=y)
	{
		for(int i=log[dep[x]];i>=0;i--)
			if(st[x][i]!=st[y][i])
			{
				x=st[x][i];
				y=st[y][i];
			}
		return st[x][0];
	}
	return x;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	log[0]=log[1]=0;
	for(int i=2;i<=n;i++)
		log[i]=log[i>>1]+1;
	int a,b,c,d;
	for(int i=1;i<=n;i++)
		head[i]=-1;
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&a,&b);
		add(a,b);
		add(b,a);
	}
	dfs(1,0);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d%d",&a,&b,&c,&d);
		int f1=lca(a,b);
		int f2=lca(c,d);
		if((dep[f1]>dep[c]&&dep[f1]>dep[d])||(dep[f2]>dep[a]&&dep[f2]>dep[b]))
		{
			printf("N\n");
			continue;
		}
		else
		{
			if(dep[f1]>dep[f2])
			{
				swap(f1,f2);
				swap(a,c);
				swap(b,d);
			}
			if(f2==lca(f2,b)||f2==lca(f2,a))
			{
				printf("Y\n");
				continue;
			}
			printf("N\n");
		}
	}
}
posted @ 2018-03-09 18:55  Lance1ot  阅读(134)  评论(0编辑  收藏  举报