lca的两种求解方法(log)
int FA[MAXN],dep[MAXN],sz[MAXN],son[MAXN],top[MAXN]; vector<int>G[MAXN]; void dfs1(int u,int fa){ sz[u]=1; dep[u]=dep[fa]+1; FA[u]=fa; for(int i=0;i<G[u].size();i++){ int v=G[u][i]; if(v==fa)continue; dfs1(v,u); sz[u]+=sz[v]; if(sz[v]>sz[son[u]])son[u]=v; } } void dfs2(int u){ if(son[u]){ top[son[u]]=top[u]; dfs2(son[u]); } for(int i=0;i<G[u].size();i++){ int v=G[u][i]; if(v==FA[u]||v==son[u])continue; top[v]=v; dfs2(v); } } int lca(int u,int v){ while(top[u]!=top[v]){ if(dep[top[u]]>dep[top[v]])swap(u,v); v=FA[top[v]]; } if(dep[u]>dep[v])swap(u,v); return u; }
这份模板需要首先对树上任意一点进行dfs1(rt);然后将top [ rt ] 设为1,之后再进行一遍dfs2(rt),然后通过输入求解lca。
倍增法求lca
for(int i=1;i<=n;i++)lg[i]=lg[i-1]+(1<<lg[i-1]==i); int lca(int x,int y){ if(h[x]<h[y])swap(x,y); while(h[x]>h[y])x=f[x][lg[h[x]-h[y]]-1]; if(x==y)return x; for(int i=lg[h[x]]-1;i>=0;i--) if(f[x][i]!=f[y][i]){ x=f[x][i]; y=f[y][i]; } return f[x][0]; }
希望用自己的努力为自己赢得荣誉。