首页 > 代码库 > 【最近公共祖先】【块状树】CODEVS 1036 商务旅行

【最近公共祖先】【块状树】CODEVS 1036 商务旅行

在线块状树LCA模板。

 1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 #define N 30001 7 vector<int>G[N]; 8 typedef vector<int>::iterator ITER; 9 int dep[N],x,y,fa[N],top[N],siz[N],sz,n,m,ans;10 int Abs(const int &x){return x<0?(-x):x;}11 void makeblock(int U)12 {13     for(ITER it=G[U].begin();it!=G[U].end();it++)14       if((*it)!=fa[U])15         {16           fa[*it]=U;17           dep[*it]=dep[U]+1;18           if(siz[top[U]]<sz)19             {20               top[*it]=top[U];21               siz[top[U]]++;22             }23           makeblock(*it);24         }25 }26 int lca(int U,int V)27 {28     while(U!=V)29       {30         if(top[U]!=top[V])31           {32             if(dep[top[U]]<dep[top[V]]) swap(U,V);33             U=fa[top[U]];34           }35         else36           {37             if(dep[U]<dep[V]) swap(U,V);38             U=fa[U];39           }40       }41     return U;42 }43 int main()44 {45     scanf("%d",&n);46     for(int i=1;i<n;i++)47       {48         scanf("%d%d",&x,&y);49         G[x].push_back(y);50         G[y].push_back(x);51       } sz=(int)sqrt((double)n);52     for(int i=1;i<=n;i++) siz[i]=1,top[i]=i;53     makeblock(1); scanf("%d%d",&m,&x);54     for(int i=2;i<=m;i++)55       {56         scanf("%d",&y); int f=lca(x,y);57         ans+=(dep[x]+dep[y]-(dep[f]<<1));58         x=y;59       }60     printf("%d\n",ans);61     return 0;62 }

【最近公共祖先】【块状树】CODEVS 1036 商务旅行