LCA 倍增模板
阿新 • • 發佈:2018-12-09
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int ,int > pii; const int N =100010; const int DEG=20; struct Edge { int v; int next; }edge[N*2]; int head[N],tot; int fa[N][21]; int deg[N]; void init() { memset(head,-1,sizeof(head)); tot=0; } void adde(int u,int v) { edge[++tot].v=v; edge[tot].next=head[u]; head[u]=tot; } void bfs(int root) { queue< int >que; deg[root]=0; que.push(root); while(!que.empty()){ int tmp=que.front(); que.pop(); for(int i=1;i<DEG;i++) fa[tmp][i]=fa[fa[tmp][i-1]][i-1]; for(int i=head[tmp];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==fa[tmp][0] ) continue; deg[v]=deg[tmp]+1; fa[v][0]=tmp; que.push(v); } } } int find_kfa(int x,int k) { for(int i=0;i<DEG;i++){ if((k>>i)&1) x=fa[x][i]; } return x; } int LCA(int u,int v) { if(deg[u]>deg[v]) swap(u,v); int hu=deg[u], hv=deg[v]; int tu=u,tv=v; for(int det=hv-hu,i=0;det;det>>=1,i++){ if(det&1) tv=fa[tv][i]; } if(tu==tv) return tu; for(int i=DEG-1;i>=0;i--){ if(fa[tu][i]==fa[tv][i]) continue; tu=fa[tu][i]; tv=fa[tv][i]; } return fa[tu][0]; } int main() { init(); adde(1,2); adde(1,3); adde(3,4); adde(3,5); adde(4,7); adde(4,8); adde(4,9); adde(5,6); int rt=1; bfs(rt); cout<<"lca "<<LCA(7,9)<<" "<<LCA(3,7)<<" "<<LCA(6,3)<<endl; return 0; }