【NOIP模拟赛】相交

【NOIP模拟赛】相交_第1张图片
题解:
因为是树所以路径一定唯一,那么我们先算出a,b的lca为f1再算出c,d的lcaf2那么不难发现是求是否有重合路径,我们先把a到b的路径拆成a到f1和b到f1两条路径,那么就是求c到f2和前两个是否有重合或者d到f2是否与前两个有重合

#include
using namespace std;
int head[100005];
int next[200005];
int ver[200005];
int d[100005];
int f[100005][25];
int tot=1,t;
int n,q;
int read(){
	int num=0;
	char ch=getchar();
	while(ch>'9'||ch<'0'){
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		num=(num<<1)+(num<<3)+ch-'0';
		ch=getchar();
	}
	return num;
}
void add(int x,int y){
	ver[++tot]=y;
	next[tot]=head[x];
	head[x]=tot;
}
void dfs(int x,int fa){
	d[x]=d[fa]+1;
	for(int j=1;j<=t;j++){
		f[x][j]=f[f[x][j-1]][j-1];
	}
	for(int i=head[x];i;i=next[i]){
		if(d[ver[i]]) continue;
		f[ver[i]][0]=x;
		dfs(ver[i],x);
	}
}
int lca(int x,int y){
	if(d[x]>d[y]) swap(x,y);
	for(int i=t;i>=0;i--){
		if(d[f[y][i]]>=d[x]) y=f[y][i];
	}
	if(x==y){
		return x;
	}
	for(int i=t;i>=0;i--){
		if(f[x][i]!=f[y][i]){
			x=f[x][i];
			y=f[y][i];
		}
	}
	return f[x][0];
}
int main(){
	n=read();
	t=log(n)/log(2)+1;
	for(int i=1;i

你可能感兴趣的:(提高组,NOIP,模拟赛,相交)