bzoj1602

题解:

简单lca

然而我调了半小时QAQ

lca的时候要判断0

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=10005;
int ne[N],l,sd[N],f[16][N],num[N],tot,fi[N],zz[N],sl[N],jin[N],n,m,x,y,z,chu[N];
void jb(int x,int y,int z)
{
    ne[++tot]=fi[x];
    fi[x]=tot;
    zz[tot]=y;
    sl[tot]=z;
}
void dfs(int x,int y)
{
    jin[x]=++l;
    f[0][x]=y;
    for (int i=fi[x];i;i=ne[i])
     if (zz[i]!=y)
      {
          sd[zz[i]]=sd[x]+1;
          num[zz[i]]=num[x]+sl[i];
          dfs(zz[i],x);
      }
    chu[x]=++l;
}
int lca(int x,int y)
{
    if (x==y)return x;
    if (sd[x]<sd[y])swap(x,y);
    for (int i=13;i>=0;i--)
     if (f[i][x]!=0&&!(jin[f[i][x]]<=jin[y]&&chu[f[i][x]]>=chu[y]))x=f[i][x];
    return f[0][x]; 
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<n;i++)
     {
         scanf("%d%d%d",&x,&y,&z);
         jb(x,y,z);jb(y,x,z);
     }
    dfs(1,0);
    for (int i=1;i<15;i++)
     for (int j=1;j<=n;j++)
      f[i][j]=f[i-1][f[i-1][j]];
    while (m--)
     {
         scanf("%d%d",&x,&y);
         printf("%d
",num[x]+num[y]-2*num[lca(x,y)]);
     } 
    return 0;
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8458297.html