有关概念:
  最近公共祖先(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的集合

 #include<cstdio>
#define MAXN
#define MAXQ
int n,Q,heade[MAXN],headq[MAXN],fa[MAXN],lca[MAXQ],dis[MAXN],cnt;
bool vis[MAXN];
struct edge
{
int v,next,val;
}e[MAXN*];
struct query
{
int u,v,next;
}q[MAXQ*];
void adde(int x,int y,int z)
{
e[++cnt].v=y;
e[cnt].next=heade[x];
heade[x]=cnt;
e[cnt].val=z;
}
void addq(int x,int y)
{
q[++cnt].u=x;
q[cnt].v=y;
q[cnt].next=headq[x];
headq[x]=cnt;
}
int getfa(int x)//并查集路径压缩
{
return fa[x]=x==fa[x]?x:getfa(fa[x]);
}
int getdis(int i)//计算路径长度
{
return dis[q[i<<].u]+dis[q[i<<].v]-*dis[lca[i]];
}
void Tarjan(int u)
{
fa[u]=u;
vis[u]=true;
for(int i=heade[u];i;i=e[i].next)
{
int v=e[i].v;
if(!vis[v])
{
dis[v]=dis[u]+e[i].val;
Tarjan(v);
fa[v]=u;
}
}
for(int i=headq[u];i;i=q[i].next)//处理询问
{
int v=q[i].u==u?q[i].v:q[i].u;
if(vis[v])lca[i>>]=getfa(fa[v]);
}
}
int main()
{
scanf("%d",&n);
int x,y,z;
for(int i=;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
adde(x,y,z);
adde(y,x,z);
}
cnt=;
scanf("%d",&Q);
for(int i=;i<=Q;i++)
{
scanf("%d%d",&x,&y);
addq(x,y);
addq(y,x);
}
Tarjan();
for(int i=;i<=Q;i++)
{
printf("%d\n",getdis(i));
}
return ;
}

图论-最近公共祖先-离线Tarjan算法的更多相关文章

  1. POJ 1330 LCA最近公共祖先 离线tarjan算法

    题意要求一棵树上,两个点的最近公共祖先 即LCA 现学了一下LCA-Tarjan算法,还挺好理解的,这是个离线的算法,先把询问存贮起来,在一遍dfs过程中,找到了对应的询问点,即可输出 原理用了并查集 ...

  2. P5836 [USACO19DEC]Milk Visits S 从并查集到LCA(最近公共祖先) Tarjan算法 (初级)

    为什么以它为例,因为这个最水,LCA唯一黄题. 首先做两道并查集的练习(估计已经忘光了).简单来说并查集就是认爸爸找爸爸的算法.先根据线索理认爸爸,然后查询阶段如果发现他们的爸爸相同,那就是联通一家的 ...

  3. 最近公共祖先LCA(Tarjan算法)的思考和算法实现

    LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...

  4. 最近公共祖先 LCA Tarjan算法

    来自:http://www.cnblogs.com/ylfdrib/archive/2010/11/03/1867901.html 对于一棵有根树,就会有父亲结点,祖先结点,当然最近公共祖先就是这两个 ...

  5. 最近公共祖先LCA(Tarjan算法)的思考和算法实现——转载自Vendetta Blogs

    LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...

  6. POJ1330Nearest Common Ancestors——近期公共祖先(离线Tarjan)

    http://poj.org/problem? id=1330 给一个有根树,一个查询节点(u,v)的近期公共祖先 836K 16MS #include<iostream> #includ ...

  7. [HDOJ2586]How far away?(最近公共祖先, 离线tarjan, 并查集)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 这题以前做过…现在用tarjan搞一发…竟然比以前暴力过的慢………… 由于是离线算法,需要Que ...

  8. POJ 1986 Distance Queries (最近公共祖先,tarjan)

    本题目输入格式同1984,这里的数据范围坑死我了!!!1984上的题目说边数m的范围40000,因为双向边,我开了80000+的大小,却RE.后来果断尝试下开了400000的大小,AC.题意:给出n个 ...

  9. 近期公共祖先(LCA)——离线Tarjan算法+并查集优化

    一. 离线Tarjan算法 LCA问题(lowest common ancestors):在一个有根树T中.两个节点和 e&sig=3136f1d5fcf75709d9ac882bd8cfe0 ...

随机推荐

  1. JavaScript中Switch使用

    switch 语句用于基于不同的条件来执行不同的动作.使用 switch 语句来选择要执行的多个代码块之一. switch(n) { case 1: 执行代码块 1 break; case 2: 执行 ...

  2. IDEA批量修改变量快捷键

    Window: Ctrl+Shift+Alt+J Mac:  Ctrl+Option+G

  3. ubuntu16.04登录后无dash,无启动栏launch,无menu bar,只有桌面背景解决办法

    今天打开电脑,与往常一样输入用户名密码登录后,发现桌面上空空如也,启动栏launch,menu bar什么的都消失了,桌面上文件可以打开,但是无法拖动位置,无法关闭(因为menu bar没了,无法鼠标 ...

  4. DOM基本代码一

    dom学习基本代码第一部分 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> < ...

  5. HDU 3487 Splay tree

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  6. 有向图的强联通分量 Tarjan算法模板

    //白书 321页 #include<iostream> #include<cstdio> #include<cstring> #include<vector ...

  7. 「模板」「讲解」Treap名次树

    Treap实现名次树 前言 学平衡树的过程可以说是相当艰难.浏览Blog的过程中看到大量指针版平衡树,不擅长指针操作的我已经接近崩溃.于是,我想着一定要写一篇非指针实现的Treap的Blog. 具体如 ...

  8. mysql 可视化界面操作指令

    1.让自增长从新开始 ALTER TABLE users auto_increment =1;//让表中的自增长从新从0开始 2.条件查询 SELECT name from  users WHERE ...

  9. Chrome切换分辨率

    不知道大家是否有遇到在Web开发的时候,老大会让你模拟不同分辨率情况,这时候,可能就有些小小的麻烦,我们可能要不断调整分辨率.是件很崩溃的事情.现在推荐一款Chrome插件.即可实现这个简单的功能. ...

  10. Asp.net Web Api 2 FORM Authentication Demo

    最近看了一点 web api 2方面的书,对认证都是简单介绍了下,所以我在这里做个简单Demo,本文主要是FORM Authentication,顺带把基本认证也讲了. Demo 一.FORM Aut ...