题目大意:求树上点对距离
题解:LCA
我的收获:2333333
#include<iostream>
#include<cstdio>
#include<queue>
#include <cstring>
using namespace std;
const long long M=50005;
struct edge{
long long from,to,val,next;
}e[M*2];
long long n,m,x,y,z,t;
long long f[M][21];
long long dis[M],dep[M],head[M];
void add(long long i,long long j,long long w)
{
e[t].from=i;
e[t].to=j;
e[t].val=w;
e[t].next=head[i];
head[i]=t++;
}
void dfs(long long u)
{
for(long long i=head[u];i!=-1;i=e[i].next)
{
long long v=e[i].to;
if(v!=f[u][0]){
f[v][0]=u;
dep[v]=dep[u]+1;
dis[v]=dis[u]+e[i].val;
dfs(v);
}
}
}
long long lca(long long x,long long y){
if(dep[x]<dep[y]) swap(x,y);
for(long long i=0;i<20;i++)if((dep[x]-dep[y])&(1<<i))x=f[x][i];
if(x==y)return x;
for(long long i=19;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
return f[x][0];
}
void init()
{
memset(head,-1,sizeof(head));
scanf("%lld%lld",&n,&m);
for(long long i=1;i<n;i++){
scanf("%lld%lld%lld",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
}
void ready()
{
for(long long j=1;j<=20;j++)
for(long long i=1;i<=n;i++)
f[i][j]=f[f[i][j-1]][j-1];
}
int main()
{
init();
dfs(1);
ready();
for(long long i=1;i<=m;i++)
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",dis[x]+dis[y]-2*dis[lca(x,y)]);
}
return 0;
}