LCA-倍增法(在线)
2014-09-13 12:33
225 查看
原文:http://www.tuicool.com/articles/N7jQV32
1. DFS预处理出所有节点的深度和父节点
2. 初始各个点的2^j祖先是谁 ,其中 2^j (j =0...log(该点深度))倍祖先,1倍祖先就是父亲,2倍祖先是父亲的父亲......。
3.从深度大的节点上升至深度小的节点同层,如果此时两节点相同直接返回此节点,即lca。
否则,利用倍增法找到最小深度的 p[a][j]!=p[b][j],此时他们的父亲p[a][0]即lca。
1. DFS预处理出所有节点的深度和父节点
inline void dfs(int u) { int i; for(i=head[u];i!=-1;i=next[i]) { if (!deep[to[i]]) { deep[to[i]] = deep[u]+1; p[to[i]][0] = u; //p[x][0]保存x的父节点为u; dfs(to[i]); } } }
2. 初始各个点的2^j祖先是谁 ,其中 2^j (j =0...log(该点深度))倍祖先,1倍祖先就是父亲,2倍祖先是父亲的父亲......。
void init() { int i,j; //p[i][j]表示i结点的第2^j祖先 for(j=1;(1<<j)<=n;j++) for(i=1;i<=n;i++) if(p[i][j-1]!=-1) p[i][j]=p[p[i][j-1]][j-1];//i的第2^j祖先就是i的第2^(j-1)祖先的第2^(j-1)祖先 }
3.从深度大的节点上升至深度小的节点同层,如果此时两节点相同直接返回此节点,即lca。
否则,利用倍增法找到最小深度的 p[a][j]!=p[b][j],此时他们的父亲p[a][0]即lca。
int lca(int a,int b)//最近公共祖先 { int i,j; if(deep[a]<deep[b])swap(a,b); for(i=0;(1<<i)<=deep[a];i++); i--; //使a,b两点的深度相同 for(j=i;j>=0;j--) if(deep[a]-(1<<j)>=deep[b]) a=p[a][j]; if(a==b)return a; //倍增法,每次向上进深度2^j,找到最近公共祖先的子结点 for(j=i;j>=0;j--) { if(p[a][j]!=-1&&p[a][j]!=p[b][j]) { a=p[a][j]; b=p[b][j]; } } return p[a][0]; }
相关文章推荐
- LCA-倍增法(在线)O(nlogn)-O(logn)
- 在线倍增法求LCA专题
- 【POJ】1330 Nearest Common Ancestors 在线LCA,倍增思想
- LCA(离线Tarjan算法,在线倍增法)详解
- 求LCA最近公共祖先的在线倍增算法模板_C++
- HDU 6065 RXD, tree and sequence(在线倍增LCA+CDQ分治+离线tarjan-LCA+dp)
- HDU6115 Factory(最近公共祖先lca,在线倍增,暴力)
- 倍增(在线)求LCA
- 倍增 - 强制在线的LCA
- LCA 在线倍增法 求最近公共祖先
- 多校第一场 1009 hdu 5296 Annoying problem(dfs序+在线倍增lca)
- HDU 6110 路径交(线段树+在线倍增LCA)
- LCA 在线倍增法 求最近公共祖先
- POJ1330 Nearest Common Ancestors(在线倍增,离线Tarjan,最近公共祖先LCA)
- CodeForces 609 E.Minimum spanning tree for each edge(最小生成树-Kruskal+在线倍增LCA)
- 在线LCA 倍增法 Codeforces Round #294 (Div. 2) E - A and B and Lecture Rooms
- LCA三种算法学习(离线算法tarjan+在线算法转rmq+在线倍增)例题poj1330、1470;hdu4547、2874
- 洛谷 P3379 【模板】最近公共祖先(LCA) (在线倍增+离线Tarjan)
- LCA (最近公共祖先)倍增做法 —— O(nlogn)预处理 O(logn)(在线)查询
- HDU 6203 ping ping ping(在线倍增LCA+BIT)