首先要知道倍增法快速求LCA,即任意两点间距离。
类比RMQ。f[x][k]表示点x向上走2^k步 点的id。(即父辈2^k,x的父亲是f[x][0])
先BFS或者DFS求出f[x][0]即初始化。
然后DP一下。
最后二进制拆分。
即利用f数组快速让x,y向上寻找LCA。
方法一:学习洛谷题解
由于树上的独特性质:向上的路径只有一条
判断AB,CD两条路径是否相交,我们只需要判断
LCA(A,C),LCA(A,D),LCA(B,C),LCA(B,D) 的深度是否大于LCA(A,B)的深度和LCA(C,D)的深度
只有任意一个满足。就说明 AB -> CD 有交点。
D_A 表示点A的深度
想一下相同起点的 AB 和AC路径
一定有一段相交,即D_LCA(A,B)深度和D_LCA(A,C)深度较大的到A这一段。在纸上画下就明白了
如果 D_LCA (A,C)>=D_LCA(A,B)&& D_LCA (A,C)>=D_LCA(C,D);
说明A->LCA(A,C)这段路径在路径A-B里, C->LCA(A,C)这段路径在路径C-D里。
那么至少会有一个点LCA(A,C)同时在AB,CD路径里,即 AB,CD路径相交
#include<bits/stdc++.h>
using namespace std;
const int M =2e5+7;
int f[M][20],d[M],dist[M],head[M];
int ct,t;
q