首页 > 搜索 > 离线tarjan算法,图论-最近公共祖先-离线Tarjan算法_weixin

离线tarjan算法,图论-最近公共祖先-离线Tarjan算法_weixin

互联网 2020-11-01 06:44:25
在线算命,八字测算命理

有关概念:最近公共祖先(LCA,Lowest Common Ancestors):对于有根树T的两个结点u、v,最近公共祖先表示u和v的深度最大的共同祖先。

Tarjan是求LCA的离线算法(先存储所有询问,再进行运算)

思路: 从根结点开始DFS,对遍历到的结点u标记已访问,创建新集合,元素为u,再遍历u的每一个儿子,回溯时将每个儿子的集合并到u的集合上,用并查集记录集合中的每个元素的fa为u,接着处理询问,对于关于u的每一个询问,若另一个结点v已访问,则可断定LCA(u,v)为fav,记录结果,最后按顺序输出即可

dis存储该结点到根结点的距离,用于计算两点之间的路径长度

样例推导(样例来自@SHHHS):

求8、6,9、7的LCA

从根结点1进入,标记访问,创建集合

访问2、4,回溯到2,新集合包含两个结点

访问5、8,处理8的询问,但6未访问,跳过

访问9,处理询问,7未访问,跳过,5、8和9并入2的集合(即fa值设为2)

访问6,处理询问,LCA(8,6)为fa8,即2

访问10,回溯,并入6的集合

回溯,并入2的集合

并入1的集合

访问3、7,处理询问,LCA(7,9)为fa9,即1

回溯,并入3的集合

并入1的集合

1 #include 2 #define MAXN 3 #define MAXQ 4 int n,Q,heade[MAXN],headq[MAXN],fa[MAXN],lca[MAXQ],dis[MAXN],cnt; 5 bool vis[MAXN]; 6 struct edge 7 { 8 int v,next,val; 9 }e[MAXN*2];10 struct query11 {12 int u,v,next;13 }q[MAXQ*2];14 void adde(int x,int y,int z)15 {16 e[++cnt].v=y;17 e[cnt].next=heade[x];18 heade[x]=cnt;19 e[cnt].val=z;20 }21 void addq(int x,int y)22 {23 q[++cnt].u=x;24 q[cnt].v=y;25 q[cnt].next=headq[x];26 headq[x]=cnt;27 }28 int getfa(int x)//并查集路径压缩29 {30 return fa[x]=x==fa[x]?x:getfa(fa[x]);31 }32 int getdis(int i)//计算路径长度33 {34 return dis[q[i
免责声明:非本网注明原创的信息,皆为程序自动获取互联网,目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责;如此页面有侵犯到您的权益,请给站长发送邮件,并提供相关证明(版权证明、身份证正反面、侵权链接),站长将在收到邮件12小时内删除。

相关阅读

一周热门

查看更多