[笔记]LCA 最近公共祖先---tarjan离线算法
来源:互联网 发布:c语言函数声明与调用 编辑:程序博客网 时间:2024/06/06 09:40
一.定义:(出自百度百科)
对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u、v的祖先且x的深度尽可能大。
二.离线算法(同上):
在开始时就需要知道问题的所有输入数据,而且在解决一个问题后就要立即输出结果。
即在算法开始前保存好所有的查询,结束后输出过程中求得的ans
三:基本思路:
看到dalao的blog,本蒟蒻已无地自容 这是借口
四.伪代码(还是楼上的)
预处理:fa[1]=1; vis[1]=1; //默认1为根
Tarjan(u)//marge和find为并查集合并函数和查找函数{ for each(u,v) //访问所有u子节点v if(!vis[v]) { 标记v被访问过:vis[v]=1; 初始化fa[v]=v; Tarjan(v); //继续往下遍历 marge(u,v); //合并v到u上 } for each(u,e) //访问所有和u有询问关系的e { 如果e被访问过; u,e的最近公共祖先为find(e); }}
五.查询的储存
类前向星
struct Query{ int to; //v int next; //下一个 int index; //查询编号};int ans[20005]; //记录ansint qcnt; //结构体大小int qhead[10005]; //u的索引Query query[40005]; inline void addQuery(int x,int y,int z) //加入{ ++qcnt; query[qcnt].to=y; query[qcnt].next=qhead[x]; query[qcnt].index=z; qhead[x]=qcnt;}
六.模板
#include <cstdio>#include <cstdlib>#define open(s) freopen(s".in","r",stdin); freopen(s".out","w",stdout);#define close fclose(stdin); fclose(stdout); using namespace std;struct Edge{ int to; int next;};int ecnt;int head[500005];Edge edge[1000005];inline void addEdge(int x,int y){ ++ecnt; edge[ecnt].to=y; edge[ecnt].next=head[x]; head[x]=ecnt;}struct Query{ int to; int next; int index;};int ans[500005];int qcnt;int qhead[500005];Query query[1000005];inline void addQuery(int x,int y,int z){ ++qcnt; query[qcnt].to=y; query[qcnt].next=qhead[x]; query[qcnt].index=z; qhead[x]=qcnt;}int vis[500005];int fa[500005];inline int read(){ int k=1; int sum=0; char c=getchar(); for(;'0'>c || c>'9' ;c=getchar()) if(c=='-') k=-1; for(;'0'<=c && c<='9';c=getchar()) sum=sum*10+c-'0'; return sum*k;}inline void write(int x){ if(x<0) { putchar('-'); x*=-1; } if(x>9) write(x/10); putchar(x%10+'0');}inline int find(int x){ return fa[x]=(fa[x]==x?x:find(fa[x]));}inline void join(int x,int y){ int x1=find(x),y1=find(y); if(x1==y1) return ; fa[y1]=x1;}inline void LCA(int p){ for(int i=head[p];i;i=edge[i].next) if(!vis[edge[i].to]) { int y=edge[i].to; vis[y]=1; fa[y]=y; LCA(y); join(p,y); } for(int i=qhead[p];i;i=query[i].next) if(!ans[query[i].index] && vis[query[i].to]) { int y=query[i].to,z=query[i].index; ans[z]=find(y); }}int main(){ open("3379"); int n=read(),m=read(); int x1=read(); for(int i=1;i<n;++i) { int x=read(),y=read(); addEdge(x,y); addEdge(y,x); } for(int i=1;i<=m;++i) { int x=read(),y=read(); addQuery(x,y,i); addQuery(y,x,i); } fa[x1]=x1; vis[x1]=1; LCA(x1); for(int i=1;i<=m;++i) { write(ans[i]); putchar('\n'); } close; return 0;}
阅读全文
0 0
- [笔记]LCA 最近公共祖先---tarjan离线算法
- LCA最近公共祖先(tarjan离线算法)
- Tarjan离线算法求最近公共祖先(LCA)
- POJ1986 DistanceQueries 最近公共祖先LCA 离线算法Tarjan
- Tarjan离线算法求最近公共祖先(LCA)
- Tarjan离线算法求最近公共祖先(LCA)
- [图论] LCA(最近公共祖先)Tarjan 离线算法
- LCA(最近公共祖先)离线算法Tarjan
- LCA(最近公共祖先) 离线法(tarjan算法)
- [图论] LCA(最近公共祖先)Tarjan 离线算法
- LCA最近公共祖先问题(Tarjan离线算法)
- LCA(最近公共祖先)离线算法之tarjan
- LCA(最近公共祖先)tarjan算法学习笔记
- 最近公共祖先LCA:Tarjan算法
- 最近公共祖先LCA Tarjan算法
- 最近公共祖先LCA Tarjan算法
- 最近公共祖先LCA Tarjan算法
- 最近公共祖先LCA:Tarjan算法
- Enqueue(队列等待)
- 【观点】英国央行官员:央行数字货币需要“非凡的”弹性
- python的内置函数
- 【资讯】盲目从众?美国银行调查显示比特币为“最拥挤交易”
- Codeforces858B which floor?
- [笔记]LCA 最近公共祖先---tarjan离线算法
- HTTP请求和响应
- Linux 根据进程名(或pid)查看其占用的端口
- BZOJ3252 攻略 [树链剖分][不用线段树]
- 【国际】博伊西市与区块链创业公司签订开发协议
- 【动态】Zcash开发人员发布新技术,改善zk-SNARK
- OpenWrt下通过EC20 R2.0 4G模块实现qmi拨号上网
- 【国际】迪拜金融监管机构发布ICO警告
- 【观点】福布斯:区块链技术是否已发展成熟?