首页 > 代码库 > 商务旅行——又是一个LCA

商务旅行——又是一个LCA

  都说要用倍增做,我就学了倍增,可是明明可以也用Tarjan 的啊,明天试一下。

技术分享
 1 #include<iostream>
 2 #include<vector>
 3 #include<cstdio>
 4 using namespace std;
 5 const int N=30086,MAXTAKE=20;
 6 int n,m,depth[N],ast[N][MAXTAKE+1],last,ans;
 7 vector<int> gr[N];
 8 void dfs(int p,int x){
 9     ast[x][0]=p;
10     for(int i=1;i<=MAXTAKE;i++)ast[x][i]=ast[ast[x][i-1]][i-1];
11     for(int i=0;i<gr[x].size();i++)
12         if(gr[x][i]!=p){
13             depth[gr[x][i]]=depth[x]+1;
14             dfs(x,gr[x][i]);
15         }
16 }
17 inline int lca(int a,int b){
18     if(depth[a]>depth[b])swap(a,b);
19     for(int i=MAXTAKE;i>=0;i--)
20         if(depth[ast[b][i]]>=depth[a])
21             b=ast[b][i];
22     if(a==b)return a;
23     for(int i=MAXTAKE;i>=0;i--)
24         if(ast[a][i]!=ast[b][i])
25             a=ast[a][i],b=ast[b][i];
26     return ast[a][0];
27 }
28 int main(){
29     cin>>n;
30     for(int i=1;i<=n;i++)
31         for(int j=0;j<=MAXTAKE;j++)
32             ast[i][j]=0;
33     for(int i=1,a,b;i<n;i++){
34         cin>>a>>b;
35         gr[a].push_back(b);
36         gr[b].push_back(a);
37     }
38     dfs(0,1);
39     cin>>m>>last;
40     for(int i=1,a;i<m;i++){
41         cin>>a;
42         ans+=depth[a]+depth[last]-2*depth[lca(a,last)];
43         last=a;
44     }
45     cout<<ans<<endl;
46     return 0;
47 }
Method_01

  Codevs 136ms.

商务旅行——又是一个LCA