HDU - 2586(倍增LCA):
多个询问求树上任意两点的距离。
import java.util.Arrays;
import java.util.Scanner;
public class Main
{
static int maxx=40005;
static int maxn=16;
static int head[]=new int[maxx];
static int to[]=new int[maxx<<1];
static int w[]=new int[maxx<<1];
static int next[]=new int[maxx<<1];
static int cnt;
static void addEdge(int x,int y,int _w)
{
to[++cnt]=y;w[cnt]=_w;next[cnt]=head[x];head[x]=cnt;
to[++cnt]=x;w[cnt]=_w;next[cnt]=head[y];head[y]=cnt;
}
static int deep[]=new int[maxx];
static int fa[][]=new int[maxx][maxn];
static int gw[][]=new int[maxx][maxn];
static int N,n;
static void init()
{
Arrays.fill(head, 0);
cnt=0;
N=(int) Math.floor(Math.log(n)/Math.log(2));
deep[1]=0;
}
static void dfs(int root)
{
for(int i=1;i<=N;i++)
{
fa[root][i]=fa[fa[root][i-1]][i-1];
gw[root][i]=gw[root][i-1]+gw[fa[root][i-1]][i-1];
}
for(int i=head[root];i>0;i=next[i])
{
int v=to[i];
if(v==fa[root][0])
continue;
deep[v]=deep[root]+1;
fa[v][0]=root;
gw[v][0]=w[i];
dfs(v);
}
}
static int LCA(int a,int b)
{
if(deep[a]>deep[b])
{
int temp=a;
a=b;
b=temp;
}
int ans=0;
for(int i=N;i>=0;i--)
{
if(deep[a]<deep[b]&&deep[a]<=deep[fa[b][i]])
{
ans+=gw[b][i];
b=fa[b][i];
}
}
for(int i=N;i>=0;i--)
{
if(fa[a][i]!=fa[b][i])
{
ans+=gw[a][i];
ans+=gw[b][i];
a=fa[a][i];
b=fa[b][i];
}
}
if(a!=b)
{
ans+=gw[a][0];
ans+=gw[b][0];
}
return ans;
}
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int t=sc.nextInt();
while(t-->0)
{
n=sc.nextInt();
int m=sc.nextInt();
init();
for(int i=1;i<n;i++)
addEdge(sc.nextInt(),sc.nextInt(),sc.nextInt());
dfs(1);
while(m-->0)
System.out.println(LCA(sc.nextInt(),sc.nextInt()));
}
}
}