• 【模板】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
    ",ans);
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    dd命令的巧妙使用
    home目录迁移至新分区
    swap分区的扩展
    搭建多系统yum服务器
    校验软件是否被黑客所修改
    源码编译安装Apache-附一键部署脚本
    yum仓库详细解读
    将FTP映射至Windows
    最简化搭建yum仓库
    校验Linux程序是否被黑客修改
  • 原文地址:https://www.cnblogs.com/DriverLao/p/7690456.html
Copyright © 2020-2023  润新知