[LUOGU3398] 仓鼠找sugar

一开始理解错题意,以为他俩速度一样,同时出发,结果发现样例也过不了。手玩一下样例,发现好像只要路径相交就行了如果路径有相交,说明有个LCA在另一条路径上,否则就有环了。然后树剖求个LCA。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=100005;
int n,q,head[N],ecnt,siz[N],fa[N],dep[N],top[N],son[N];
int rd() {
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
struct Edge{int to,nxt;}e[N<<1];
void add(int bg,int ed){e[++ecnt].to=ed;e[ecnt].nxt=head[bg];head[bg]=ecnt;swap(bg,ed);e[++ecnt].to=ed;e[ecnt].nxt=head[bg];head[bg]=ecnt;}
void dfs(int x) {
	siz[x]=1;
	for(int i=head[x];i;i=e[i].nxt) {
		if(e[i].to==fa[x]) continue;
		int v=e[i].to;dep[v]=dep[x]+1;fa[v]=x;dfs(v);siz[x]+=siz[v];
		son[x]=siz[v]>siz[son[x]]?v:son[x];
	}
}
void dfs(int x,int qtop) {
	top[x]=qtop;
	if(!son[x]) return;
	dfs(son[x],qtop);
	for(int i=head[x];i;i=e[i].nxt) {
		int v=e[i].to;
		if(v==fa[x]||v==son[x]) continue;
		dfs(v,v);
	}
}
int lca(int x,int y) {
	while(top[x]!=top[y])
		(dep[top[x]]>=dep[top[y]])?x=fa[top[x]]:y=fa[top[y]];
	return dep[x]<dep[y]?x:y;
}
int main() {
	n=rd(),q=rd();
	for(int i=1;i<n;i++)add(rd(),rd());
	dfs(1);dfs(1,1);
	int a,b,c,d,lcaa,lcab;
	while(q--) {
		a=rd(),b=rd(),c=rd(),d=rd();
		lcaa=lca(a,b),lcab=lca(c,d);
		if(dep[lcaa]<dep[lcab]) {
			swap(lcaa,lcab),swap(a,c),swap(b,d);
		}
		if(lca(lcaa,c)==lcaa||lca(lcaa,d)==lcaa) puts("Y");
		else puts("N");
	}
}
我是咸鱼。转载博客请征得博主同意Orz
原文地址:https://www.cnblogs.com/sdfzhsz/p/9412124.html