标准求法
//O(nlogn)-O(logn) #include<cstdio> #include<algorithm> using namespace std; const int maxn=100010; int first[maxn],next[maxn*2],to[maxn*2],dis[maxn*2]; int n,m; void AddEdge(int a,int b,int c) { to[++m]=b; dis[m]=c; next[m]=first[a]; first[a]=m; } int dep[maxn],fa[maxn],cost[maxn],anc[20][maxn]; void dfs(int x) { dep[x]=dep[fa[x]]+1; for(int i=first[x];i;i=next[i]) { if(to[i]!=fa[x]) { fa[to[i]]=x; cost[to[i]]=cost[x]+dis[i]; dfs(to[i]); } } } void preprocess() { for(int i=1;i<=n;i++) anc[0][i]=fa[i]; for(int j=1;(1<<j)<=n;j++) for(int i=1;i<=n;i++) if(anc[j-1][i]) { int a=anc[j-1][i]; anc[j][i]=anc[j-1][a]; } } int LCA(int p,int q) { if(dep[p]<dep[q]) swap(p,q); int log=1; for(;(1<<log)<=dep[p];log++); log--; for(int i=log;i>=0;i--) if(dep[p]-dep[q]>=(1<<i)) p=anc[i][p]; if(p==q) return p; for(int i=log;i>=0;i--) if(anc[i][p]!=anc[i][q]) { p=anc[i][p]; q=anc[i][q]; } return fa[p]; } int main() { int a,b,c,Q; scanf("%d",&n); for(int i=1;i<n;i++) { scanf("%d%d%d",&a,&b,&c); AddEdge(a,b,c); AddEdge(b,a,c); } scanf("%d",&Q); dfs(1); preprocess(); while(Q--) { scanf("%d%d",&a,&b); c=LCA(a,b); printf("%d %d\n",dep[a]+dep[b]-dep[c]*2+1,cost[a]+cost[b]-cost[c]*2); } return 0; }