【codevs 1036】商务旅行

来源:互联网 发布:java string类源码分析 编辑:程序博客网 时间:2024/06/05 19:35

lca

#include<cstdio>#include<iostream>#include<algorithm>#include<queue>#include<cmath>#include<cstring>using namespace std;const int maxn=30000+5;int fa[maxn][25],deep[maxn],dist[maxn];int n,m,tot,first[maxn],next[maxn<<1];struct edge{    int f,t,v;}es[maxn<<1];void build(int f,int t,int v){    es[++tot]=(edge){f,t,v};    next[tot]=first[f];    first[f]=tot;}void init(int q,int h){    for(int i=first[h];i;i=next[i])    {        int at=es[i].t,av=es[i].v;        if(at==q) continue;        fa[at][0]=h;        dist[at]=dist[h]+av;        deep[at]=deep[h]+1;        init(h,at);    }}void make_lca(){    for(int i=1;i<=log2(n);i++)      for(int j=1;j<=n;j++)        fa[j][i]=fa[fa[j][i-1]][i-1];}int lca(int x,int y){    if(deep[x]<deep[y]) swap(x,y);    for(int i=log2(m);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(){    scanf("%d",&n);    for(int i=1;i<n;i++)    {        int v,u;        scanf("%d%d",&v,&u);        build(v,u,1);        build(u,v,1);    }    init(1,1);    make_lca();    scanf("%d",&m);    int ans=0;    for(int i=1;i<=m;i++)    {        int a,la;        scanf("%d",&a);        if(i==1)  la=a;        else         {            ans+=dist[a]+dist[la]-2*(dist[lca(a,la)]);            la=a;        }    }    printf("%d\n",ans);    return 0;}