【模板】Lca倍增法

Codevs 1036 商务旅行

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=100010;
 6 int n,m,x,y,ans=0,tot=0,last[maxn],dep[maxn],p[maxn][32];
 7 struct edge{
 8     int to,pre;
 9 }e[maxn<<1];
10 
11 void read(int &k){
12     k=0; int f=1; char c=getchar();
13     while (c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
14     while ('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
15     k*=f;
16 }
17 void add(int x,int y){
18     e[++tot].to=y;
19     e[tot].pre=last[x];
20     last[x]=tot;
21 }
22 void dfs(int u,int fa){
23     dep[u]=dep[fa]+1; p[u][0]=fa;
24     for (int i=1;i<=log2(dep[u]);i++) p[u][i]=p[p[u][i-1]][i-1];
25     for (int i=last[u],to=e[i].to;i;i=e[i].pre,to=e[i].to)
26     if (to!=fa) dfs(to,u);
27 }
28 int lca(int x,int y){
29     if (dep[x]<dep[y]) swap(x,y);
30     if (dep[x]>dep[y])
31     for (int i=log2(dep[x]-dep[y]+1);i>=0,dep[x]!=dep[y];i--)
32         if (dep[p[x][i]]>=dep[y]) x=p[x][i];
33      if (x==y) return x;
34      for (int i=log2(dep[x]);i>=0;i--)
35      if (p[x][i]!=p[y][i]) x=p[x][i],y=p[y][i];
36      return p[x][0];
37 }
38 int main(){
39     read(n);
40     for (int i=1;i<n;i++){
41         read(x); read(y);
42         add(x,y); add(y,x);
43     }
44     dfs(1,0);
45     read(m); read(x);
46     for (int i=1;i<m;i++){
47         read(y);
48         ans+=dep[x]+dep[y]-(dep[lca(x,y)]<<1);
49         x=y;
50     }
51     printf("%d\n",ans);
52     return 0;
53 }
View Code

 

posted @ 2017-10-19 07:13  Driver_Lao  阅读(165)  评论(0编辑  收藏  举报