有关概念:
  最近公共祖先(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. 【bzoj1026】[SCOI2009]windy数 数位dp

    题目描述 windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? 输入 包含两个整数 ...

  2. CentOS 双网卡绑定实现平衡负载

    绑定两块网卡主要为了解决网卡故障.负载均衡等问题. 1.在vm加一块网卡,登录后检查网卡是否识别. 分别用ip addr和nmcli查看网卡的情况 [root@bigdata-senior01 ~]# ...

  3. BZOJ3526 [Poi2014]Card 【线段树】

    题目链接 BZOJ3526 题解 思来想去,发现很显然可以用线段树维护 每个区间保存所有合法方案的左右端点[当左端点一定是,右端点当然存最小的那个就行了] 这么整的数,\(\frac{1}{1000} ...

  4. NOIP2016Day2T3愤怒的小鸟(状压dp) O(2^n*n^2)再优化

    看这范围都知道是状压吧... 题目大意就不说了嘿嘿嘿 网上流传的写法复杂度大都是O(2^n*n^2),这个复杂度虽然官方数据可以过,但是在洛谷上会TLE[百度搜出来前几个博客的代码交上去都TLE了], ...

  5. X day3

    题目 官方题解 T1: 一道水题 #include<iostream> #include<cstring> #include<cstdio> #include< ...

  6. 【状压DP】【UVA11825】 Hackers' Crackdown

    传送门 Description 你是一个hacker,侵入了一个有着n台计算机(编号为1.2.3....n)的网络.一共有n种服务,每台计算机都运行着所有服务.对于每台计算机,你都可以选择一项服务,终 ...

  7. Apache 403 错误解决方法-让别人可以访问你的服务器(转)

    有一次做好了一个效果放在自己电脑的服务器上,让同学查看(同处于校园网中),却不知apache一直显示403 错误,对方没有权限访问,我知道这应该是配置文件httpd.conf中的问题,网上搜了一下其他 ...

  8. best code #54 div 2 A 水

    A problem of sorting Accepts: 443 Submissions: 1696 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  9. DOM动态操纵控件案例

    点击登陆显示登陆框 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head ...

  10. POJ2155 树状数组

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 26650   Accepted: 9825 Descripti ...