求LCA:
//暴力
int n,m,root,fa[N],dep[N];
void dfs(int u,int fath){
fa[u]=fath;
dep[u]=dep[fath]+1;
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(v==fath) continue;
dfs(v,u);
}
}
int lca(int x,int y){
while(x!=y){
if(dep[x]<dep[y]) swap(x,y);
else x=fa[x];
}
return x;
}
//倍增
int dep[N],anc[N][65],maxlog=40;
int n,m,root;
void dfs(int u,int fa){
dep[u]=dep[fa]+1;
anc[u][0]=fa;
for(int i=1;i<=maxlog;i++){
anc[u][i]=anc[anc[u][i-1]][i-1];
}
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(fa==v) continue;
dfs(v,u);
}
}
int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=maxlog;i>=0;i--){
if(dep[anc[x][i]]>=dep[y]) x=anc[x][i];
}
if(x==y) return x;
for(int i=maxlog;i>=0;i--){
if(anc[x][i]!=anc[y][i]){
x=anc[x][i];
y=anc[y][i];
}
}
return anc[x][0];
}
//tarjan 离线算法,应该较为少用,算了 之后补上
//树剖
int son[N],siz[N],top[N],dep[N],fa[N];
void init(int s){
dep[s]=1;
for(int i=1;i<=n;i++){
siz[i]=1;
son[i]=-1;
}
}
void dfs1(int u){
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(dep[v]) continue;
fa[v]=u;
dep[v]=dep[u]+1;
dfs1(v);
siz[u]+=siz[v];
if(siz[son[u]]<siz[v]) son[u]=v;
}
}
void dfs2(int u,int d){
top[u]=d;
if(son[u]==-1) return ;
dfs2(son[u],d);
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(v==son[u]||v==fa[u]) continue;
dfs2(v,v);
}
}
int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if(dep[x]<dep[y]) return x;
else return y;
}