BZOJ 1602: [Usaco2008 Oct]牧场行走 倍增裸题
Code:
#include <bits/stdc++.h>
#define maxn 10000
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int hd[maxn],to[maxn],nex[maxn],val[maxn],dep[maxn],f[23][maxn],len[maxn];
int cnt;
void add(int u,int v,int c){
nex[++cnt]=hd[u],hd[u]=cnt,to[cnt]=v,val[cnt]=c;
}
void dfs(int u,int fa){
f[0][u]=fa;
for(int i=1;i<=20;++i) f[i][u]=f[i-1][f[i-1][u]];
for(int i=hd[u];i;i=nex[i]) {
if(to[i]==fa) continue;
len[to[i]]=len[u]+1, dep[to[i]]=dep[u]+val[i],dfs(to[i],u);
}
}
int lca(int a,int b){
if(len[a]>len[b]) swap(a,b);
if(len[a]!=len[b]){
for(int i=20;i>=0;--i) if(len[f[i][b]] >= len[a]) b=f[i][b];
}
if(a==b) return a;
for(int i=20;i>=0;--i) {
if(f[i][a]!=f[i][b]) a=f[i][a],b=f[i][b];
}
return f[0][a];
}
int dis(int a,int b){
return dep[a]+dep[b]-(dep[lca(a,b)]<<1);
}
int main(){
// setIO("input");
int n,q;
scanf("%d%d",&n,&q);
for(int i=1,a,b,c;i<n;++i){
scanf("%d%d%d",&a,&b,&c);
add(a,b,c),add(b,a,c);
}
dfs(1,0);
while(q--){
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",dis(a,b));
}
return 0;
}