LCA(Lowest Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先。

Tarjan是一种离线算法,时间复杂度O(n+Q),Q表示询问次数,其中使用倍增法加速算法。

首先dfs建立二叉树,并标记深度、父节点。

在LCA函数中,交换x、y保证x深度最大,计算深度差,在进行有限次计算后,保持x、y深度一致,再次进行多次倍增,寻找到最近公共祖先

最后计算节点距离差:deep[x]+deep[y]-deep[t]*2

 #include<iostream>
#include<cstdio>
using namespace std; const int MAXN=;
struct Edge
{
int to,next;
}E[MAXN];
int node,head[MAXN];
int deep[MAXN],fa[MAXN][];
bool vis[MAXN];
int n,m,ans;
int a[MAXN]; void insert(int u,int v)
{
E[++node]=(Edge){v,head[u]};head[u]=node;
E[++node]=(Edge){u,head[v]};head[v]=node;
} void dfs(int x)
{
vis[x]=;
for(int i=;i<=;i++)
{
if(deep[x]<(<<i)) break;
fa[x][i]=fa[fa[x][i-]][i-];
}
for(int i=head[x];i;i=E[i].next)
{
if(vis[E[i].to]) continue;
deep[E[i].to]=deep[x]+;
fa[E[i].to][]=x;
dfs(E[i].to);
}
} int lca(int x,int y)
{
if(deep[x]<deep[y]) swap(x,y);
int d=deep[x]-deep[y];
for(int i=;i<=;i++)
if((<<i)&d) x=fa[x][i];
for(int i=;i>=;i--)
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
if(x==y) return x;
else return fa[x][];
} int dis(int x,int y)
{
int t=lca(x,y);
return deep[x]+deep[y]-deep[t]*;
} int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
insert(x,y);
}
dfs();
scanf("%d",&m);
for(int i=;i<=m;i++)
scanf("%d",&a[i]);
for(int i=;i<m;i++)
ans+=dis(a[i],a[i+]);
printf("%d",ans);
return ;
}

LCA最近公共祖先——Tarjan模板的更多相关文章

  1. LCA 最近公共祖先 tarjan离线 总结 结合3个例题

    在网上找了一些对tarjan算法解释较好的文章 并加入了自己的理解 LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通 ...

  2. lca最近公共祖先(模板)

    洛谷上的lca模板题--传送门 学了求lca的tarjan算法(离线),在洛谷上做模板题,结果后三个点超时. 又把询问改成链式前向星,才ok. 这个博客,tarjan分析的很详细. 附代码-- #in ...

  3. HDU 4547 CD操作 (LCA最近公共祖先Tarjan模版)

    CD操作 倍增法  https://i.cnblogs.com/EditPosts.aspx?postid=8605845 Time Limit : 10000/5000ms (Java/Other) ...

  4. LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现

    首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵 ...

  5. LCA最近公共祖先 Tarjan离线算法

    学习博客:  http://noalgo.info/476.html 讲的很清楚! 对于一颗树,dfs遍历时,先向下遍历,并且用并查集维护当前节点和父节点的集合.这样如果关于当前节点(A)的关联节点( ...

  6. LCA 最近公共祖先 (模板)

    #include <iostream> #include <stdio.h> #include <cstring> #include <vector> ...

  7. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)

    Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...

  8. LCA(最近公共祖先)模板

    Tarjan版本 /* gyt Live up to every day */ #pragma comment(linker,"/STACK:1024000000,1024000000&qu ...

  9. LCA 近期公共祖先 小结

    LCA 近期公共祖先 小结 以poj 1330为例.对LCA的3种经常使用的算法进行介绍,分别为 1. 离线tarjan 2. 基于倍增法的LCA 3. 基于RMQ的LCA 1. 离线tarjan / ...

随机推荐

  1. OLEDB 参数化查询

    一般情况下,SQL查询是相对固定的,一条语句变化的可能只是条件值,比如之前要求查询二年级学生信息,而后面需要查询三年级的信息,这样的查询一般查询的列不变,后面的条件只有值在变化,针对这种查询可以使用参 ...

  2. 菜鸟学习Spring——SpringIoC容器基于三种配置的对比

    一.概述 对于实现Bean信息定义的目标,它提供了基于XML.基于注解及基于java类这三种选项.下面总结一下三种配置方式的差异. 二.Bean不同配置方式比较. 三.Bean不同配置方式的适用场合. ...

  3. Format - DateTime

    1. Long Date/Short Date/Long Time/Short Time,可以在系统的“Region and Language”中找到相应设置: 2. ISO Format/Local ...

  4. SOL的补充

    之前写过一些关于远程安装系统的文档,但是对于SOL还是糊涂不清. Serial Console 可以将输入输出转发到串行接口(com1, com2), 假如你有串行读取设备,就可以看到显示,控制输入. ...

  5. 卡方分布、卡方独立性检验和拟合性检验理论及其python实现

    如果你在寻找卡方分布是什么?如何实现卡方检验?那么请看这篇博客,将以通俗易懂的语言,全面的阐述卡方.卡方检验及其python实现. 1. 卡方分布 1.1 简介 抽样分布有三大应用:T分布.卡方分布和 ...

  6. 西汉姆VS利物浦,铁锤『拳』出击,打回原『菱』形

    一.铁锤,还是铁桶?   铁锤帮西汉姆今晚摆出4-2-3-1对阵红军利物浦的4-3-3 ,阿勒戴斯曾在主场2-1战胜赫尔城时被球迷嘘,嫌他的足球太过丑陋『2010年的时候贝尼特斯也曾经诟病阿勒戴斯带队 ...

  7. html css:背景图片链接css写法

    图片作为背景,并且是链接的写法.例如网站的logo图片.例如:土豆的logo图片 <a title="土豆网 tudou.com 每个人都是生活的导演" href=" ...

  8. Hive创建外部表以及分区

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/sheismylife/article/details/27874943 创建带分区的外部表 创建外部 ...

  9. js中json对象取键和值

    1.json中输出各个键值: var ohp = {"星期一":18,"星期二":16,"星期三":19,"星期四":1 ...

  10. JavaEE权限管理系统的搭建(六)--------使用拦截器实现菜单URL的跳转权限验证和页面的三级菜单权限按钮显示

    本小结讲解,点击菜单进行页面跳转,看下图,点击管理员列表后会被认证拦截器首先拦截,验证用户是否登录,如果登录就放行,紧接着会被权限验证拦截器再次拦截,拦截的时候,会根据URL地址上找到对应的方法,然后 ...