【模板】LCA

来源:互联网 发布:telnet连接linux 编辑:程序博客网 时间:2024/06/05 00:34

原题codevs2370

#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 150005;int n,m,f,t,v,tot = 0;int first[MAXN],next[MAXN];int deep[MAXN],fa[MAXN][35],rank[MAXN];struct edge{    int f,t,v;}l[MAXN];void build(int f,int t,int v){    l[++ tot] = (edge){f,t,v};    next[tot] = first[f];    first[f] = tot;    return;}void make_tree(int x,int f,int v){    deep[x] = deep[f] + 1;    fa[x][0] = f;rank[x] = v;    for(int i = first[x]; i != -1; i = next[i])        if(l[i].t != f) make_tree(l[i].t,x,v + l[i].v);    return;}void make_lca(){    for(int j = 1; j <= log2(n); j ++)        for(int i = 1; i <= n; i ++)            fa[i][j] = fa[fa[i][j - 1]][j - 1];    return;}int lca(int x,int y){    if(deep[x] < deep[y]) swap(x,y);    for(int i = log2(n); i >= 0; i --)        if(deep[fa[x][i]] >= deep[y])            x = fa[x][i];    if(x == y)  return x;    for(int i = log2(n); i >= 0; i --)        if(fa[x][i] != fa[y][i])            x = fa[x][i],y = fa[y][i];    return fa[x][0];}int main(){    memset(first,0xff,sizeof(first));    scanf("%d",&n);    for(int i = 1; i < n; i ++)    {        scanf("%d %d %d",&f,&t,&v);        build(f,t,v);        build(t,f,v);    }    make_tree(0,n,0);    make_lca();    scanf("%d",&m);    for(int i = 1; i <= m; i ++)    {        scanf("%d %d",&f,&t);        printf("%d\n",rank[f] + rank[t] - (rank[lca(f,t)] << 1));    }    return 0;}
0 0
原创粉丝点击