codevs 1036 商务旅行

Posted on 2015-12-30 14:59  ziliuziliu  阅读(205)  评论(0编辑  收藏  举报

 这题有毒。。。。。。什么鬼的数据范围。

 LCA模板题。

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxv 300050
#define maxe 300050
using namespace std;
long long n,g[maxv],nume=0,anc[maxv][30],ask[maxv],m;
long long dis[maxv],sum;
long long lca;
bool vis[maxv];
struct edge
{
long long v,nxt;
}e[maxe];
void addedge(long long u,long long v)
{
e[++nume].v=v;
e[nume].nxt=g[u];
g[u]=nume;
}
void dfs(long long u,long long fath)
{
anc[u][0]=fath;
dis[u]=dis[fath]+1;
vis[u]=true;
for (long long i=g[u];i;i=e[i].nxt)
{
if (vis[e[i].v]==false)
dfs(e[i].v,u);
}
}
void jump(long long i)
{
long long u=ask[i-1],v=ask[i];
long long ku=u,kv=v;
if (dis[u]<dis[v])
{
for (long long i=25;i>=0;i--)
{
if (dis[anc[v][i]]>=dis[u])
v=anc[v][i];
}
}
else if (dis[u]>dis[v])
{
for (long long i=25;i>=0;i--)
{
if (dis[anc[u][i]]>=dis[v])
u=anc[u][i];
}
}
if (u==v)
lca=u;
else
{
for (long long i=25;i>=0;i--)
{
if (anc[u][i]!=anc[v][i])
{
u=anc[u][i];
v=anc[v][i];
}
}
lca=anc[u][0];
}
sum=sum+dis[ku]+dis[kv]-2*dis[lca];
}
int main()
{
memset(dis,0,sizeof(dis));
memset(anc,0,sizeof(anc));
memset(vis,false,sizeof(vis));
scanf("%lld",&n);
long long u,v;
for (long long i=1;i<=n-1;i++)
{
scanf("%lld%lld",&u,&v);
addedge(u,v);
addedge(v,u);
}
dis[0]=-1;
dfs(1,0);
scanf("%lld",&m);
for (long long i=1;i<=m;i++)
scanf("%lld",&ask[i]);
sum=0;
for (long long e=1;e<=25;e++)
for (long long j=1;j<=n;j++)
anc[j][e]=anc[anc[j][e-1]][e-1];
for (long long i=2;i<=m;i++)
jump(i);
printf("%lld",sum);
return 0;
}