商务旅行——又是一个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.

  然后是小小地将小机房的树的源码改了一下,也可以直接做出来。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<vector>
 4 using namespace std;
 5 const int N=77777;
 6 //Constants;//
 7 int n,m;
 8 vector<int> gr[N],dis[N],qpnt[N],qnum[N];
 9 //INput;//
10 int fth[N],ans;
11 unsigned long long len[N];
12 bool vis[N],vt[N];
13 //Usage;//
14 int fnd(int x){
15     return (fth[x]==x?x:fnd(fth[x]));
16 }
17 void uni(int x,int y){
18     int tmp=fnd(y);
19     if(tmp!=x)fth[tmp]=x;
20 }
21 void dfs(int x,int d){
22     len[x]=d;
23     for(int i=0;i<gr[x].size();i++)
24         if(!vt[gr[x][i]]){
25             vt[gr[x][i]]=true;
26             dfs(gr[x][i],d+1);
27             uni(x,gr[x][i]);
28         }
29     vis[x]=true;
30     for(int i=0;i<qpnt[x].size();i++)
31         if(vis[qpnt[x][i]])
32             ans+=len[qpnt[x][i]]+len[x]-2*len[fnd(qpnt[x][i])];
33 }
34 //Function(s);//
35 int main(){
36     for(int i=1;i<N;i++)fth[i]=i;
37     //Pre-INput;//
38     cin>>n;
39     for(int i=1;i<n;i++){
40         int x,y;cin>>x>>y;
41         gr[x].push_back(y);
42         gr[y].push_back(x);
43     }
44     int x,last;
45     cin>>m>>last;
46     for(int i=1;i<m;i++){
47         cin>>x;
48         qpnt[x].push_back(last);
49         qpnt[last].push_back(x);
50         last=x;
51     }
52     //INput;//
53     vt[1]=true;
54     dfs(1,0);
55     //Calculating;//
56     cout<<ans<<endl;
57     //OUTput;//
58     return 0;
59 }
Method_02

  CodeVS 174ms.

posted @ 2017-06-28 22:21  Darkins  阅读(113)  评论(0)    收藏  举报