思路
lca模板题。
注意数组大小,稍微比范围大一点,不然怎么死的都不知道。
代码
#include<iostream>
#include<cstdio>
using namespace std;
int dep[100010],dis[100010],f[100010][25];
int hd[100010],tot;
int n,m,x,y,k;
struct node
{
int y,next,z;
}a[100010];
void add(int x,int y,int w)
{
a[++tot]=(node){y,hd[x],w};
hd[x]=tot;
}
void finddep(int x,int fa)
{
f[x][0]=fa;
dep[x]=dep[fa]+1;
for(int i=hd[x]; i; i=a[i].next)
{
int yy=a[i].y;
if(yy==fa)
continue;
dis[yy]=dis[x]+a[i].z;
finddep(yy,x);
}
}
int lca(int x,int y)
{
if(dep[x]>dep[y])
swap(x,y);
int p=dep[y]-dep[x],k=20,t=1<<k;
while(p)
{
if(t<=p)
p-=t,y=f[y][k];
k--,t=1<<k;
}
if(x==y)
return x;
for(int i=20; i>=0; i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int main()
{
cin>>n>>m;
for(int i=1; i<=n-1; i++)
{
scanf("%d%d%d",&x,&y,&k);
add(x,y,k);
add(y,x,k);
}
finddep(1,0);
for(int j=1; (1<<j)<=n; j++)
for(int i=1; i<=n; i++)
f[i][j]=f[f[i][j-1]][j-1];
while(m--)
{
scanf("%d%d",&x,&y);
int ans=lca(x,y);
printf("%d\n",dis[x]-dis[ans]+dis[y]-dis[ans]);
}
return 0;
}