都说要用倍增做,我就学了倍增,可是明明可以也用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.
时间: 2024-12-25 20:42:42