倍增法求lca 模板
2017-06-06 18:41
337 查看
struct tree { int from,to,w; tree(int ff,int tt,int ww) { from=ff;to=tt;w=ww; } tree(){} }; vector<tree>G; vector<int>V[M*2]; int mxdeep; int father [30]; //记录祖先结点编号 int deep ; //记录结点深度 int dis [30]; //记录结点和祖先结点的距离 void addtree(int from,int to,int w) //建边 { G.push_back(tree(from,to,w)); G.push_back(tree(to,from,w)); int e=G.size(); V[from].push_back(e-2); V[to].push_back(e-1); } void init(int n) { memset(father,0,sizeof(father)); memset(deep,0,sizeof(deep)); memset(dis,0,sizeof(dis)); mxdeep=log(n*1.0)/log(2.0); G.clear(); for(int i=0;i<=M;i++) V[i].clear(); } void dfs(int root) //根结点是输入时father[v][0]=0的点. { for(int i=1;i<=mxdeep;i++) { father[root][i]=father[father[root][i-1]][i-1]; dis[root][i]=dis[father[root][i-1]][i-1]+dis[root][i-1]; if(!father[root][i]) //优化,当为0的时候说明已经更新到了根结点位置 break; } for(int i=0;i<V[root].size();i++) { tree &e=G[V[root][i]]; if(e.to!=father[root][0]) //说明e.to是root的儿子 { deep[e.to]=deep[root]+1; father[e.to][0]=root; //建立父子关系 dis[e.to][0]=e.w; //更新到父亲的距离 dfs(e.to); } } } int lca(int u,int v) { int ans=0; if(deep[u]>deep[v]) //让u结点不在v结点下方,方便操作 swap(u,v); for(int i=mxdeep;i>=0;i--) //将 v结点上移,但不能高于u结点 { if(deep[u]<deep[v]&&deep[u]<=deep[father[v][i]]) { ans+=dis[v][i]; v=father[v][i]; } } if(v==u) return ans; for(int i=mxdeep;i>=0;i--) { if(father[v][i]!=father[u][i]) //一起移动到共同父亲处 { ans+=dis[v][i]+dis[u][i]; v=father[v][i]; u=father[u][i]; } } if(v!=u) ans+=dis[v][0]+dis[u][0]; // 如果没有移动到同一处,可能是 1->u 1->v ,那么向上移动一个位置就可以了 return ans; }
相关文章推荐
- 倍增lca模板
- 倍增LCA模板
- 倍增求LCA的模板
- 倍增LCA 模板
- {模板}LCA倍增
- 倍增求lca模板
- Hdu 2586 How far away ?【倍增LCA模板记录】
- 倍增LCA模板
- lca(最近公共祖先)倍增模板【pascal】
- hdu 5296 lca+dfs应用,lca倍增法模板
- 【模板】【LCA】【树上倍增】
- 倍增求lca(模板)
- 【模板】倍增LCA [2017年5月计划 清北学堂51精英班 Day3]
- LCA模板——倍增法
- 洛谷 P3379 【模板】最近公共祖先(LCA) (在线倍增+离线Tarjan)
- 求LCA最近公共祖先的在线倍增算法模板_C++
- czl蒟蒻的模板库6——倍增LCA
- LCA Tarjan及倍增模板(POJ 1330)
- 【模板】倍增法求lca
- 【模板】倍增LCA