LCA的tarjan算法
void LCA(int u) { p[u]=u; visit[u]=true; for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].to; if(!visit[v]) { LCA(v); p[v]=u; } } for(int i=qhead[u]; i!=-1; i=qedge[i].next) { int v=qedge[i].to; if(visit[v]) { qedge[i].lca=find(v); qedge[i^1].lca=qedge[i].lca; } } }
倍增法
#define MAXN 1111 #define MAX_LOG_V 20 struct node { int to,next; }; node edge[2*MAXN]; int head[MAXN],tot; void add_edge(int u,int v) { edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } int parent[MAX_LOG_V][MAXN]; int depth[MAXN],in[MAXN]; void dfs(int u,int p,int d) { parent[0][u]=p; depth[u]=d; for(int i=head[u]; i!=-1; i=edge[i].next) if(edge[i].to!=p) dfs(edge[i].to,u,d+1); } void init(int n) { int root; for(int i=1; i<=n; i++) if(!in[i]) { root=i; break; } dfs(root,-1,0); for(int k=0; k+1<MAX_LOG_V; k++) { for(int v=1; v<=n; v++) if(parent[k][v]<0) parent[k+1][v]=-1; else parent[k+1][v]=parent[k][parent[k][v]]; } } int lca(int u,int v) { if(depth[u]>depth[v]) swap(u,v); for(int k=0; k<MAX_LOG_V; k++) if((depth[v]-depth[u])>>k&1) v=parent[k][v]; if(u==v) return u; for(int k=MAX_LOG_V-1; k>=0; k--) if(parent[k][v]!=parent[k][u]) { u=parent[k][u]; v=parent[k][v]; } return parent[0][u]; }