您的位置:首页 > 其它

【codevs 1036】商务旅行

2017-09-02 09:57 239 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: