LCA
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; const int maxn=50010; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=10*x+ch-'0';ch=getchar();} return x*f; } int first[maxn],to[2*maxn],next[2*maxn],val[2*maxn],cnt; int st[maxn][50]; int vis[maxn]; int dis[maxn]; int depth[maxn],f[maxn]; void add(int a,int b,int c) { to[++cnt]=b; next[cnt]=first[a]; first[a]=cnt; val[cnt]=c; } void ins(int a,int b,int c){add(a,b,c);add(b,a,c);} void dfs(int x) { st[x][0]=f[x]; for(int i=1;i<=31;i++)st[x][i]=st[st[x][i-1]][i-1]; for(int i=first[x];i;i=next[i]) { if(to[i]==f[x])continue; f[to[i]]=x; depth[to[i]]=depth[x]+1; dis[to[i]]=val[i]+dis[x]; dfs(to[i]); } } pair<int,int> lca(int u,int v) { int a=u,b=v; if(depth[u]<depth[v])swap(u,v),swap(a,b); for(int i=31;i>=0;i--) if(depth[v]<depth[st[u][i]])u=st[u][i]; if(u==v)return make_pair(v,dis[a]-dis[v]); for(int i=31;i>=0;i--) { if(st[u][i]==st[v][i])break; u=st[u][i],v=st[v][i]; } return make_pair(st[u][0],dis[a]+dis[b]-(dis[st[u][0]]<<1)); } int main() { int n,q; scanf("%d",&n); for(int i=1;i<n;i++) { int u=read(),v=read(),w=read(); ins(u,v,w); } depth[1]=1; vis[1]=1; dfs(1); q=read(); pair<int,int> ans; for(int i=1;i<=q;i++) { int u,v; u=read(),v=read(); ans=lca(u,v); cout<<ans.first<<" "<<ans.second<<endl; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; const int maxn=50010; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=10*x+ch-'0';ch=getchar();} return x*f; } int first[maxn],to[2*maxn],next[2*maxn],val[2*maxn],cnt; int qfirst[maxn],qto[2*maxn],qnext[2*maxn],qval[2*maxn],qcnt,qdis[2*maxn],idq[maxn]; int n,q; int vis[maxn]; int depth[maxn],fa[maxn]; int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} void Unite(int x,int y){if(find(x)!=find(y))fa[find(x)]=find(y);} void add(int a,int b) { to[++cnt]=b; next[cnt]=first[a]; first[a]=cnt; } void ins(int a,int b){add(a,b);add(b,a);} void qadd(int a,int b) { qto[++qcnt]=b; qnext[qcnt]=qfirst[a]; qfirst[a]=qcnt; } void qins(int a,int b){qadd(a,b);qadd(b,a);} void Tarjan_dfs(int x,int f) { int lca; fa[x]=x; vis[x]=1; for(int i=first[x];i;i=next[i]) { if(to[i]==f)continue; vis[to[i]]=1; depth[to[i]]=depth[x]+1; Tarjan_dfs(to[i],x); Unite(to[i],x); } for(int i=qfirst[x];i;i=qnext[i]) { if(vis[qto[i]]) { lca=find(qto[i]); qval[idq[i]]=lca; qdis[idq[i]]=depth[qto[i]]+depth[x]-(depth[lca]<<1); } } } int main() { n=read(),q=read(); int u,v; for(int i=1;i<n;i++) { u=read(),v=read(); ins(u,v); } for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=q;i++) { u=read(),v=read(); qadd(u,v);idq[qcnt]=i; qadd(v,u);idq[qcnt]=i; } depth[1]=1; Tarjan_dfs(1,1); for(int i=1;i<=q;i++)cout<<qval[i]<<endl; }