LCA系列 hdu2587

http://acm.hdu.edu.cn/showproblem.php?pid=2586

好久不写LCA了

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 1e5+10;
struct tree
{
    struct Edge{
        int from,to,cost;
        Edge(){}
        Edge(int x,int y,int z):from(x),to(y),cost(z){}
    }edges[N];
    int E,head[N],Next[N],dep[N],fa[N][20];
    LL di[N][20];
    bool vis[N];

    inline void Init()
    {
        E = 0;
        memset(head,-1,sizeof(head));
        memset(Next,-1,sizeof(Next));
        memset( vis, 0,sizeof( vis));
    }

    inline void link(int x,int y,int z)
    {
        edges[++E] = Edge(x,y,z);
        Next[E] = head[x];
        head[x] = E;
    }

    void dfs(int x)
    {
        vis[x] = 1;
        for (int i=1;i<17;i++)if (dep[x]>= 1<<i){
            fa[x][i] = fa[fa[x][i-1]][i-1];
            di[x][i] = di[x][i-1] + di[fa[x][i-1]][i-1];
        }
        for (int i=head[x];i!=-1;i=Next[i]){
            Edge e = edges[i];
            if (vis[e.to])continue;
            dep[e.to] = dep[x] + 1;
            fa[e.to][0] = x;
            di[e.to][0] = e.cost;
            dfs(e.to);
        }
    }

    inline int lca(int x,int y)
    {
        if (dep[x]<dep[y])swap(x,y);
        int t = dep[x] - dep[y];
        for (int i=0;i<=16;i++)
            if (t&(1<<i)) x = fa[x][i];
        for (int i=16;i>=0;i--)
            if (fa[x][i]!=fa[y][i]){
            x = fa[x][i]; y = fa[y][i];
        }
        if (x == y) return x;
        return fa[x][0];
    }

    inline LL ask(int x,int f)
    {
        int t = dep[x] - dep[f];
        LL ans = 0;
        for (int i=0;i<17;i++)if (t&(1<<i)){
            ans += di[x][i];
            x = fa[x][i];
        }
        return ans;
    }
} g ;

int main()
{
    int T,n,m,x,y,z;
    scanf("%d",&T);
    for (;T--;){
        scanf("%d%d",&n,&m);
        g.Init();
        for (int i=1;i<n;i++){
            scanf("%d%d%d",&x,&y,&z);
            g.link(x,y,z);
            g.link(y,x,z);
        }
        g.dep[1] = 0;
        g.dfs(1);
        for (;m--;){
            scanf("%d%d",&x,&y);
            int f = g.lca(x,y);
            LL ans = g.ask(x,f) + g.ask(y,f);
            printf("%I64d
",ans);
        }
    }
    return 0;
}

马住,慢慢填
http://www.cnblogs.com/scau20110726/archive/2013/06/14/3135095.html

原文地址:https://www.cnblogs.com/cww97/p/7533960.html