LCA(Tarjan算法)模板
一.查询一组的LCA
Nearest Common Ancestors
In the figure, each node is labeled with an integer from {1,
2,...,16}. Node 8 is the root of the tree. Node x is an ancestor of node
y if node x is in the path between the root and node y. For example,
node 4 is an ancestor of node 16. Node 10 is also an ancestor of node
16. As a matter of fact, nodes 8, 4, 10, and 16 are the ancestors of
node 16. Remember that a node is an ancestor of itself. Nodes 8, 4, 6,
and 7 are the ancestors of node 7. A node x is called a common ancestor
of two different nodes y and z if node x is an ancestor of node y and an
ancestor of node z. Thus, nodes 8 and 4 are the common ancestors of
nodes 16 and 7. A node x is called the nearest common ancestor of nodes y
and z if x is a common ancestor of y and z and nearest to y and z among
their common ancestors. Hence, the nearest common ancestor of nodes 16
and 7 is node 4. Node 4 is nearer to nodes 16 and 7 than node 8 is.
For other examples, the nearest common ancestor of nodes 2
and 3 is node 10, the nearest common ancestor of nodes 6 and 13 is node
8, and the nearest common ancestor of nodes 4 and 12 is node 4. In the
last example, if y is an ancestor of z, then the nearest common ancestor
of y and z is y.
Write a program that finds the nearest common ancestor of two distinct nodes in a tree.
Input
is given in the first line of the input file. Each test case starts with
a line containing an integer N , the number of nodes in a tree,
2<=N<=10,000. The nodes are labeled with integers 1, 2,..., N.
Each of the next N -1 lines contains a pair of integers that represent
an edge --the first integer is the parent node of the second integer.
Note that a tree with N nodes has exactly N - 1 edges. The last line of
each test case contains two distinct integers whose nearest common
ancestor is to be computed.
Output
Sample Input
2
16
1 14
8 5
10 16
5 9
4 6
8 4
4 10
1 13
6 15
10 11
6 7
10 2
16 3
8 1
16 12
16 7
5
2 3
3 4
3 1
1 5
3 5
Sample Output
4
3 使用链式前向星存图得到的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX 10010
struct node
{
int to;
int next;
} edge[MAX];
int head[MAX];
int f[MAX];
int vis[MAX];
int is_root[MAX];
int n;
int cnt;
int cx,cy;
int ans;
int Find(int x)
{
if(x!=f[x])
f[x]=Find(f[x]);
return f[x];
} void Join(int x,int y)///合并集合
{
int fx=Find(x);
int fy=Find(y);
if(fx!=fy)
{
f[fy]=fx;
}
} void add_edge(int x,int y)
{
edge[cnt].to=y;
edge[cnt].next=head[x];
head[x]=cnt++;
} void LCA(int u)
{
int i,v;
for(i=head[u]; i!=-; i=edge[i].next)
{
v=edge[i].to;
LCA(v);
Join(u,v);
vis[v]=;
}
if(cx==u&&vis[cy]==)
{
ans=Find(cy);
}
if(cy==u&&vis[cx]==)
{
ans=Find(cx);
}
}
int main()
{
int T,i;
int root;
scanf("%d",&T);
while(T--)
{ memset(head,-,sizeof(head));
memset(vis,,sizeof(vis));
memset(is_root,,sizeof(is_root));
scanf("%d",&n);
cnt=;
for(i=; i<=n; i++)
f[i]=i;
for(i=; i<n; i++)
{
int x,y;
scanf("%d%d",&x,&y);
add_edge(x,y);
is_root[y]=;
}
for(i=; i<=n; i++)///找根节点
{
if(is_root[i]==)///入度为0的则是根节点
{
root=i;
}
}
scanf("%d%d",&cx,&cy);///单组查询
LCA(root);
printf("%d\n",ans);
}
return ;
}
二.查询多组的LCA
Closest Common Ancestors
Input
nr_of_vertices
vertex:(nr_of_successors) successor1 successor2 ... successorn
...
where vertices are represented as integers from 1 to n ( n
<= 900 ). The tree description is followed by a list of pairs of
vertices, in the form:
nr_of_pairs
(u v) (x y) ...
The input file contents several data sets (at least one).
Note that white-spaces (tabs, spaces and line breaks) can be used freely in the input.
Output
number of pair for which it is an ancestor. The results are printed on
the standard output on separate lines, in to the ascending order of the
vertices, in the format: ancestor:times
For example, for the following tree:
Sample Input
5
5:(3) 1 4 2
1:(0)
4:(0)
2:(1) 3
3:(0)
6
(1 5) (1 4) (4 2)
(2 3)
(1 3) (4 3)
Sample Output
2:1
5:5
Hint
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX 1010
struct node
{
int to;
int next;
} edge[MAX];
int head[MAX];
int f[MAX];
int vis[MAX];
int is_root[MAX];
int que[MAX][MAX];///新开一个数组记录要查询的两个点
int ans[MAX];
int n;
int cnt;
int cx,cy;
int Find(int x)
{
if(x!=f[x])
f[x]=Find(f[x]);
return f[x];
} void Join(int x,int y)
{
int fx=Find(x);
int fy=Find(y);
if(fx!=fy)
{
f[fy]=fx;
}
} void add_edge(int x,int y)
{
edge[cnt].to=y;
edge[cnt].next=head[x];
head[x]=cnt++;
} void LCA(int u)
{
int i,v;
for(i=head[u]; i!=-; i=edge[i].next)
{
v=edge[i].to;
LCA(v);
Join(u,v);
vis[v]=;
}
for(i=; i<=n; i++)///访问所有与u有关系的点
{
if(vis[i]&&que[u][i])
{
ans[Find(i)]+=que[u][i];
}
}
}
int main()
{
int T,i,j,t;
int root;
int x,y;
int num;
while(scanf("%d",&n)!=EOF)
{
memset(head,-,sizeof(head));
memset(vis,,sizeof(vis));
memset(is_root,,sizeof(is_root));
memset(que,,sizeof(que));
memset(ans,,sizeof(ans));
cnt=;
for(i=; i<=n; i++)
{
f[i]=i;
}
for(i=; i<=n; i++)
{ scanf("%d:(%d)",&x,&num);
for(j=; j<=num; j++)
{
scanf("%d",&y);
add_edge(x,y);
is_root[y]=;
}
}
scanf("%d",&t);
for(i=; i<=t; i++)
{
scanf(" (%d %d)",&x,&y);
que[x][y]++;
que[y][x]++;
}
for(i=; i<=n; i++)
{
if(is_root[i]==)
{
root=i;
}
}
LCA(root);
for(i=; i<=n; i++)
{
if(ans[i])
{
printf("%d:%d\n",i,ans[i]);
}
}
}
return ;
}
LCA(Tarjan算法)模板的更多相关文章
- HDU 2586 ( LCA/tarjan算法模板)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:n个村庄构成一棵无根树,q次询问,求任意两个村庄之间的最短距离 思路:求出两个村庄的LCA,d ...
- [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]
参考: 1. 郭华阳 - 算法合集之<RMQ与LCA问题>. 讲得很清楚! 2. http://www.cnblogs.com/lazycal/archive/2012/08/11/263 ...
- Tarjan 算法求 LCA / Tarjan 算法求强连通分量
[时光蒸汽喵带你做专题]最近公共祖先 LCA (Lowest Common Ancestors)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili tarjan LCA - YouTube Tarj ...
- Tarjan 算法&模板
Tarjan 算法 一.算法简介 Tarjan 算法一种由Robert Tarjan提出的求解有向图强连通分量的算法,它能做到线性时间的复杂度. 我们定义: 如果两个顶点可以相互通达,则称两个顶点强连 ...
- 最近公共祖先LCA(Tarjan算法)的思考和算法实现
LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...
- POJ 1330 Nearest Common Ancestors(LCA Tarjan算法)
题目链接:http://poj.org/problem?id=1330 题意:给定一个n个节点的有根树,以及树中的两个节点u,v,求u,v的最近公共祖先. 数据范围:n [2, 10000] 思路:从 ...
- LCA:Tarjan算法实现
本博文转自http://www.cnblogs.com/JVxie/p/4854719.html,转载请注明出处 首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有 ...
- 最近公共祖先LCA(Tarjan算法)的思考和算法实现——转载自Vendetta Blogs
LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...
- Tarjan算法(模板)
算法思想: 首先要明确强连通图的概念,一个有向图中,任意两个点互相可以到达:什么是强连通分量?有向图的极大连通子图叫强连通分量. 给一个有向图,我们用Tarjan算法把这个图的子图(在这个子图内,任意 ...
- hdu 2586 How far away ?(LCA - Tarjan算法 离线 模板题)
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
随机推荐
- Java并发编程(十)死锁
哲学家进餐问题 并发执行带来的最棘手的问题莫过于死锁了,死锁问题中最经典的案例就是哲学家进餐问题:5个哲学家坐在一个桌子上,桌子上有5根筷子,每个哲学家的左手边和右手边各有一根筷子.示意图如下: 哲学 ...
- 在TextBrowser显示中,如何让最新的数据永远出现在第一行或者是在窗口的最后显示信息
这是第一行,但是随着数据的增多,最新的数据就会在末尾显示,然后就看不到了.可以用 main_ui->ReceiveDatatextBrowser->insertPlainText(strD ...
- 浅谈fastDFS服务器
FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.FastDFS特别适合以文件为载体的 ...
- scrapy基础
scrapy Scrapy 是用 Python 实现的一个为了爬取网站数据.提取结构性数据而编写的应用框架. Scrapy 常应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. Scrapy ...
- [译]C语言实现一个简易的Hash table(2)
上一章,简单介绍了Hash Table,并提出了本教程中要实现的几个Hash Table的方法,有search(a, k).insert(a, k, v)和delete(a, k),本章将介绍Hash ...
- iOS 基于APNS消息推送原理与实现(包括JAVA后台代码)
Push的原理: Push 的工作机制可以简单的概括为下图 图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider. APNS 是Apple ...
- STM32 HAL库学习系列第5篇 定时器TIM---编码器接口模式配置
cube基本配置,外设开启编码器,串口2 可能大家在设置的时候有这个错误 错误:error: #20: identifier "TIM_ICPOLARITY_BOTHEDGE" ...
- CAN总线的学习
CAN(controller Area Network )总线的学习 1986 年德国电气商博世公司开发出面向汽车的CAN 通信协议(数据之间的交互),其目的是为适应“减少线束的数量”.“通过多个LA ...
- python2.7入门---XML解析
首先我们先来考虑,什么是XML?XML 指可扩展标记语言(eXtensible Markup Language).XML 被设计用来传输和存储数据.XML是一套定义语义标记的规则,这些标记将文 ...
- # 第二周课堂实践以及MyOD
第二周课堂实践以及MyOD 之前使用的虚拟机出现问题被我删掉了,开始学着使用Mac系统自带的终端.在课堂上出现了问题,询问王雄老师也没有解决,课下先使用了实验楼环境进行实验,后来又在Mac重新进行了尝 ...