LCA(最近公共祖先)倍增法模板及总结
2017-04-03 10:41
393 查看
还是markdown编辑器好啊
写lca写了一段时间 有ST表的在线查询方法但是我一直没写AC过。。。。所以先把倍增的丢这里好了
复杂度O(nlogn) ,n是dfs用的 logn是倍增往上跳用的。。。。然后大致的思路就是 在dfs时记每个点的深度 求2点lca时先将两点跳到同一深度 再一起跳到同一点 至于每个这样的距
4000
离一定会由2的整次幂组成 所以一定会在最后跳到lca下一层的位置。
好吧也许你不知道我在说什么 看代码你也许就懂了
写lca写了一段时间 有ST表的在线查询方法但是我一直没写AC过。。。。所以先把倍增的丢这里好了
复杂度O(nlogn) ,n是dfs用的 logn是倍增往上跳用的。。。。然后大致的思路就是 在dfs时记每个点的深度 求2点lca时先将两点跳到同一深度 再一起跳到同一点 至于每个这样的距
4000
离一定会由2的整次幂组成 所以一定会在最后跳到lca下一层的位置。
好吧也许你不知道我在说什么 看代码你也许就懂了
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <vector> #include <queue> using namespace std; const int maxn=500000+50; const int maxm=500000+50; const int max_log_n=20; int n,m,s; struct edge { int to,next; }; edge es[maxn<<1]; int head[maxn]; int pa[20][maxn]; int depth[maxn]; int cnt=0; void addedge(int from,int to) { es[cnt].to=to; es[cnt].next=head[from]; head[from]=cnt++; } void dfs(int v,int fa) { pa[0][v]=fa; if(v!=s) depth[v]=depth[fa]+1; else depth[v]=1; int k=1; if(pa[k-1][v]!=-1) { while(pa[k-1][pa[k-1][v]]!=-1) { pa[k][v]=pa[k-1][pa[k-1][v]]; k++; } } for(int j=head[v];j>=0;j=es[j].next) { int u=es[j].to; if(u!=fa) { dfs(u,v); } } } void iniparent() { int k; for(int i=1;i<=n;i++) { k=1; if(pa[k-1][i]!=-1) { while(pa[k-1][pa[k-1][i]]!=-1) { pa[k][i]=pa[k-1][pa[k-1][i]]; k<<=1; } } } } int lca(int v,int u) { if(depth[u]>depth[v]) { swap(u,v); } if(depth[u]!=depth[v]) { for(int i=max_log_n-1;i>=0;i--) { if(((depth[v]-depth[u])>>i)&1) { v=pa[i][v]; } } } if(u==v) { return u; } else { for(int k=max_log_n-1;k>=0;k--) { if(pa[k][u]!=pa[k][v]) { v=pa[k][v]; u=pa[k][u]; } } return pa[0][v]; } } void ini() { memset(pa,-1,sizeof(pa)); for(int i=0;i<maxn;i++) { es[i].to=-1; es[i].next=-1; } memset(head,-1,sizeof(head)); } int main() { //freopen("1.out","w",stdout); ini(); scanf("%d",&n); for(int i=0;i<n-1;i++) { int from,to; scanf("%d%d",&from,&to); addedge(from,to); addedge(to,from); } s=1; dfs(s,-1); scanf("%d",&m); //iniparent(); for(int j=1;j<=m;j++) { int u,v; scanf("%d%d",&u,&v); printf("%d\n",lca(u,v)); } return 0; }
相关文章推荐
- 倍增法求最近公共祖先(LCA)的算法模板
- hdu 2586 How far away ? 最近公共祖先lca 在线算法(倍增法)/离线算法(Tarjan算法)
- tarjan离线算法-LCA最近公共祖先算法模板(详细)
- P3379 【模板】最近公共祖先(LCA)
- LCA 最近公共祖先 tarjan离线 总结 结合3个例题
- 洛谷——P3379 【模板】最近公共祖先(LCA)
- 图论--最近公共祖先问题(LCA)模板
- (倍增)最近公共祖先(LCA)模板
- 洛谷 P 3379 【模板】最近公共祖先(LCA)
- 洛谷P3379 【模板】最近公共祖先(LCA)
- P3379 【模板】最近公共祖先(LCA)
- LCA最近公共祖先 在线算法和离线算法 模板
- LCA 最近公共祖先 tarjan离线 总结 结合3个例题
- 洛谷 P3379 【模板】最近公共祖先(LCA)
- 最近公共祖先LCA模板(Tarjan/RMQ)
- 算法模板——LCA(最近公共祖先)
- 最近公共祖先LCA【模板】
- 模板_LCA(最近公共祖先)
- HDU 2586 How far away ?(LCA模板 最近公共祖先啊)
- lca最近公共祖先(模板)