http://codevs.cn/problem/2370/
#include<bits/stdc++.h> using namespace std; const int M=5e4+5; const int N=20; struct node{ int v,w; node(int vv=0,int ww=0):v(vv),w(ww){} }; vector<node>e[M]; int n,grand[M][N],dis[M][N],deep[M],book[M],root,s; void dfs(int u){ for(int i=1;i<=s;i++){ grand[u][i]=grand[grand[u][i-1]][i-1]; dis[u][i]=dis[u][i-1]+dis[grand[u][i-1]][i-1]; if(!grand[u][i]) break; } for(int i=0;i<e[u].size();i++){ int v=e[u][i].v; if(v!=grand[u][0]){ grand[v][0]=u; deep[v]=deep[u]+1; dis[v][0]=e[u][i].w; dfs(v); } } } void init(){ s=floor(log(1.0*n)/log(2.0)); deep[0]=-1; dfs(root); } int LCA(int a,int b){ if(deep[a]>deep[b]) swap(a,b); int ans=0; for(int i=s;i>=0;i--){ if(deep[a]<deep[b]&&deep[a]<=deep[grand[b][i]]) ans+=dis[b][i],b=grand[b][i]; } for(int i=s;i>=0;i--){ if(grand[a][i]!=grand[b][i]) ans+=dis[a][i],ans+=dis[b][i],a=grand[a][i],b=grand[b][i]; } if(a!=b) ans+=dis[a][0]+dis[b][0]; return ans; } int main(){ scanf("%d",&n); for(int i=1;i<n;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); u++; v++;///fu book[u]=1; e[u].push_back(node(v,w)); e[v].push_back(node(u,w)); } for(int i=1;i<=n;i++){ if(!book[i]){ root=i; break; } } init(); int m; scanf("%d",&m); while(m--){ int u,v; scanf("%d%d",&u,&v); u++,v++; printf("%d\n",LCA(u,v)); } return 0; }
、