LCA[倍增][树剖][tarjan]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LCA[倍增][树剖][tarjan]相关的知识,希望对你有一定的参考价值。
LCA:最近公共祖先
倍增:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<vector> 5 using namespace std; 6 #define N 105 7 int deep[N],dad[N][21]; 8 vector<int>vec[N]; 9 int lca(int x,int y) { 10 if(deep[x]>deep[y])swap(x,y); 11 for(int i=20;i>=0;i--) 12 if(deep[dad[y][i]]>=deep[x])y=dad[y][i]; 13 if(x==y)return x; 14 for(int i=20;i>=0;i--) 15 if(dad[x][i]!=dad[y][i])x=dad[x][i],y=dad[y][i]; 16 return dad[x][0]; 17 } 18 void dfs(int x) { 19 deep[x]=deep[dad[x][0]]+1; 20 for(int i=0;dad[x][i];i++) 21 dad[x][i+1]=dad[dad[x][i]][i]; 22 for(int i=0;i<vec[x].size();i++) 23 if(!deep[vec[x][i]])dad[vec[x][i]][0]=x,dfs(vec[x][i]); 24 } 25 int main() { 26 int n,Q,u,v,x,y; 27 scanf("%d",&n); 28 for(int i=1;i<n;i++) { 29 scanf("%d%d",&u,&v); 30 vec[u].push_back(v); 31 vec[v].push_back(u); 32 } 33 dfs(1); 34 scanf("%d",&Q); 35 while(Q--) { 36 scanf("%d%d",&x,&y); 37 printf("%d\n",lca(x,y)); 38 } 39 return 0; 40 }
树剖:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 #define N 105 7 int deep[N],top[N],dad[N],size[N]; 8 vector<int>vec[N]; 9 void dfs(int x) { 10 size[x]=1;deep[x]=deep[dad[x]]+1; 11 for(int i=0;i<vec[x].size();i++) 12 if(vec[x][i]!=dad[x]) { 13 dad[vec[x][i]]=x; 14 dfs(vec[x][i]); 15 size[x]+=size[vec[x][i]]; 16 } 17 } 18 void dfs1(int x) { 19 int t=0;if(!top[x])top[x]=x; 20 for(int i=0;i<vec[x].size();i++) 21 if(vec[x][i]!=dad[x]&&size[vec[x][i]]>size[t])t=vec[x][i]; 22 if(t)top[t]=top[x],dfs1(t); 23 for(int i=0;i<vec[x].size();i++) 24 if(vec[x][i]!=dad[x]&&vec[x][i]!=t)dfs1(vec[x][i]); 25 } 26 int lca(int x,int y) { 27 while(top[x]!=top[y]) { 28 if(deep[top[x]]<deep[top[y]])swap(x,y); 29 x=dad[x]; 30 } 31 if(deep[x]>deep[y])swap(x,y); 32 return x; 33 } 34 int main() { 35 int n,u,v,Q,x,y; 36 scanf("%d",&n); 37 for(int i=1;i<n;i++) { 38 scanf("%d%d",&u,&v); 39 vec[u].push_back(v); 40 vec[v].push_back(u); 41 } 42 dfs(1); 43 dfs1(1); 44 scanf("%d",&Q); 45 while(Q--) { 46 scanf("%d%d",&x,&y); 47 printf("%d\n",lca(x,y)); 48 } 49 return 0; 50 }
tarjan
1 #include<cstdio> 2 #include<vector> 3 using namespace std; 4 #define N 1105 5 int fa[N],qx[N],qy[N],ans[N],dad[N],x,y; 6 vector<int>vec[N],que[N]; 7 int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);} 8 int dfs(int x) { 9 fa[x]=x; 10 for(int i=0;i<vec[x].size();i++) 11 if(dad[x]!=vec[x][i]) 12 dad[vec[x][i]]=x,dfs(vec[x][i]); 13 for(int i=0;i<que[x].size();i++) 14 if(dad[y=qx[que[x][i]]^qy[que[x][i]]^x]) 15 ans[que[x][i]]=find(y); 16 fa[x]=dad[x]; 17 } 18 int main() { 19 int n,m; 20 scanf("%d%d",&n,&m); 21 for(int i=1;i<n;i++) { 22 scanf("%d%d",&x,&y); 23 vec[x].push_back(y); 24 vec[y].push_back(x); 25 } 26 for(int i=1;i<=m;i++) { 27 scanf("%d%d",&qx[i],&qy[i]); 28 que[qx[i]].push_back(i); 29 que[qy[i]].push_back(i); 30 } 31 dfs(1); 32 for(int i=1;i<=m;i++) 33 printf("%d\n",ans[i]); 34 return 0; 35 }
我会补发注释的
以上是关于LCA[倍增][树剖][tarjan]的主要内容,如果未能解决你的问题,请参考以下文章