LCA最近公共祖先 在线算法和离线算法 模板
来源:互联网 发布:麦田的守望者 知乎 编辑:程序博客网 时间:2024/05/19 22:02
原理讲解:http://dongxicheng.org/structure/lca-rmq/
在线算法模板:
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int INF=0x3f3f3f; const int maxn=111111; const int maxm=111111; int n,m; struct EDGENODE{ int to; int w; int next; }; struct SGRAPH{ int head[maxn]; EDGENODE edges[maxm]; int edge; void init(){ memset(head,-1,sizeof(head)); edge=0; } void addedge(int u,int v,int c){ edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++; } //------------ int d[maxn][20]; //元素从1编号到n void makeRmqIndex(int A[],int n){ for(int i=1;i<=n;i++) d[i][0]=i; for(int j=1;(1<<j)<=n;j++) for(int i=1;i+(1<<j)-1<=n;i++) d[i][j] = A[d[i][j-1]] < A[d[i+(1<<(j-1))][j-1]]? d[i][j-1]:d[i+(1<<(j-1))][j-1]; } int rmqIndex(int L,int R,int A[]) { int k=0; while ((1<<(k+1))<=R-L+1) k++; return A[d[L][k]]<A[d[R-(1<<k)+1][k]]? d[L][k]:d[R-(1<<k)+1][k]; } //--------------------- int E[maxn*2],R[maxn],D[maxn*2],mn; void dfs(int u,int p,int d){ E[++mn]=u; D[mn]=d; R[u]=mn; for (int i=head[u];i!=-1;i=edges[i].next){ int v=edges[i].to; if (v==p) continue; dfs(v,u,d+1); E[++mn]=u; D[mn]=d; } } void LCA_init(){ mn=0; memset(R,0,sizeof(R)); dfs(1,-1,1); makeRmqIndex(D,mn); getd(1,-1,0); } int LCA(int u,int v){ if (R[u]>=R[v]) return E[rmqIndex(R[v],R[u],D)]; else return E[rmqIndex(R[u],R[v],D)]; } //-------------------- int deep[maxn]; void getd(int u,int p,int w){ deep[u]=w; for (int i=head[u];i!=-1;i=edges[i].next){ int v=edges[i].to; if (v==p) continue; getd(v,u,w+edges[i].w); } } int getDis(int u,int v){ int lca=LCA(u,v); return deep[u]+deep[v]-deep[lca]*2; } int done(int x,int y,int z){ int ans=INF,res=0; int lca1,lca2; lca1=LCA(x,y); res=deep[x]+deep[y]-deep[lca1]*2; lca2=LCA(lca1,z); res+=deep[lca1]+deep[z]-deep[lca2]*2; ans=min(ans,res); lca1=LCA(x,z); res=deep[x]+deep[z]-deep[lca1]*2; lca2=LCA(lca1,y); res+=deep[lca1]+deep[y]-deep[lca2]*2; ans=min(ans,res); lca1=LCA(y,z); res=deep[y]+deep[z]-deep[lca1]*2; lca2=LCA(lca1,x); res+=deep[lca1]+deep[x]-deep[lca2]*2; ans=min(ans,res); return ans; } }solver;
离线求解:
/**LCA(离线算法)主函数除建边外还应调用init();dir[1]=0;tarjan(1);*/#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int maxn=40010;struct note{ int u,v,w,lca,next;}edge[maxn*2],edge1[805];int head[maxn],ip,head1[maxn],ip1;///需要建两次边。1,该树的边2,需要查询的两点int m,n;int father[maxn],vis[maxn],dir[maxn];///依次表示u点的祖先、标记是否访问过,到根节点的距离void init(){ memset(vis,0,sizeof(vis)); memset(dir,0,sizeof(dir)); memset(head,-1,sizeof(head)); memset(head1,-1,sizeof(head1)); ip=ip1=0;}void addedge(int u,int v,int w){ edge[ip].v=v,edge[ip].w=w,edge[ip].next=head[u],head[u]=ip++;}void addedge1(int u,int v){ edge1[ip1].u=u,edge1[ip1].v=v,edge1[ip1].lca=-1,edge1[ip1].next=head1[u],head1[u]=ip1++;}int Find(int x){ if(father[x]==x) return x; return father[x]=Find(father[x]);}void Union(int x,int y){ x=Find(x); y=Find(y); if(x!=y) father[y]=x;}void tarjan(int u){ vis[u]=1; father[u]=u; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; int w=edge[i].w; if(!vis[v]) { dir[v]=dir[u]+w; tarjan(v); Union(u,v); } } for(int i=head1[u];i!=-1;i=edge1[i].next) { int v=edge1[i].v; if(vis[v]) { edge1[i].lca=edge1[i^1].lca=father[Find(v)]; } }}
0 0
- LCA最近公共祖先 在线算法和离线算法 模板
- 最近公共祖先(LCA):离线&在线算法
- LCA最近公共祖先的离线算法(Tarjan)和在线算法(ST)
- LCA最近公共祖先(tarjan离线算法)
- 最近公共祖先LCA离线算法
- tarjan离线算法-LCA最近公共祖先算法模板(详细)
- 最近公共祖先(LCA)算法实现过程 【Tarjan离线+倍增在线+RMQ】
- 算法基础 - 最近公共祖先(在线算法/离线算法)
- LCA最近公共祖先算法
- LCA最近公共祖先算法
- LCA最近公共祖先算法
- LCA(最近公共祖先)问题的离线算法
- Tarjan离线算法求最近公共祖先(LCA)
- POJ1986 DistanceQueries 最近公共祖先LCA 离线算法Tarjan
- Tarjan离线算法求最近公共祖先(LCA)
- LCA(最近公共祖先)问题的离线算法
- Tarjan离线算法求最近公共祖先(LCA)
- [图论] LCA(最近公共祖先)Tarjan 离线算法
- 蓝桥杯--微生物增值
- iOS 自定义滑动返回和解决连续多次push,pop引起的crash问题
- edittext失去焦点
- bzoj3685题解(普通van Emde Boas树)
- JSONModel的原理
- LCA最近公共祖先 在线算法和离线算法 模板
- Nginx.conf 中状态信息
- mfc学习笔记(2)——vector容器类型
- VS2010中创建安装项目
- ZOJ 3818 Pretty Poem (暴力模拟 string(substr))
- 网络图片浏览器
- codeforces 24A Ring road
- 利用可变参数,将调试信息写入文件log.txt中
- 如何完成一篇高质量的论文(笔记)