求LCA最近公共祖先的离线Tarjan算法_C++
2016-09-04 21:31
232 查看
这个Tarjan算法是求LCA的算法,不是那个强连通图的
它是 离线 算法,时间复杂度是 O(m+n),m 是询问数,n 是节点数
它的优点是比在线算法好写很多
不过有些题目是强制在线的,此类离线算法就无法使用了
另附上在线ST算法的链接:
http://www.cnblogs.com/hadilo/p/5837517.html
直接上伪代码:
源代码中将询问用栈分节点一个个压入,而且克隆了单次询问,如询问 1 5 节点,则将 5 压入 1 的栈中,并且将 5 压入 1 的栈中
因为当询问时会有一次另一个还未加入并查集的情况
版权所有,转载请联系作者,违者必究
QQ:740929894
它是 离线 算法,时间复杂度是 O(m+n),m 是询问数,n 是节点数
它的优点是比在线算法好写很多
不过有些题目是强制在线的,此类离线算法就无法使用了
另附上在线ST算法的链接:
http://www.cnblogs.com/hadilo/p/5837517.html
直接上伪代码:
源代码中将询问用栈分节点一个个压入,而且克隆了单次询问,如询问 1 5 节点,则将 5 压入 1 的栈中,并且将 5 压入 1 的栈中
因为当询问时会有一次另一个还未加入并查集的情况
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #include<stack> #define N 100001 using namespace std; int down ,next ,f ,ans ,n; stack<int> s ,num ; int find(int x) { return f[x]==x?x:f[x]=find(f[x]); } void dfs(int x) { f[x]=x; int i; for (i=down[x];i!=0;i=next[i]) { dfs(i); f[find(f[i])]=find(f[x]); } while (!s[x].empty()) { if (f[s[x].top()]!=s[x].top()) ans[num[x].top()]=find(f[s[x].top()]); s[x].pop(); num[x].pop(); } } int main() { freopen("lca.in","r",stdin); freopen("lca.out","w",stdout); int i,x,y,t,root; scanf("%d",&n); for (i=1;i<=n;i++) { scanf("%d",&x); next[i]=down[x]; down[x]=i; if (x==0) root=i; } scanf("%d",&t); for (i=1;i<=t;i++) { scanf("%d%d",&x,&y); if (x==y) ans[i]=x; s[x].push(y); s[y].push(x); num[x].push(i); num[y].push(i); } dfs(root); for (i=1;i<=t;i++) printf("%d\n",ans[i]); return 0; }
版权所有,转载请联系作者,违者必究
QQ:740929894
相关文章推荐
- 求LCA最近公共祖先的在线ST算法_C++
- 求LCA最近公共祖先的在线ST算法_C++
- 求LCA最近公共祖先的在线倍增算法模板_C++
- c++最近公共祖先LCA(倍增算法和tarjan)
- 最近公共祖先LCA Tarjan算法
- LCA----最近公共祖先
- 最近公共祖先LCA 【@Abandon】
- LCA问题:求二叉树中任意两个节点的最近公共祖先
- 最近公共祖先(least common ancestors,LCA)
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)
- HDU 2874 LCA 最近公共祖先
- 【HDU 2586 How far away ?】 邻接表+dfs+LCA(最近公共祖先问题)
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)
- SOJ 1187 最近公共祖先 LCA
- 最近公共祖先(LCA)
- Lca 最近公共祖先
- 【POJ1330】最近公共祖先(LCA):并查集+深搜
- 最近公共祖先LCA的几种解决方案
- LCA(最近公共祖先)问题
- 最近公共祖先(LCA)的Tarjan算法