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 ...
随机推荐
- docker之MySQL主从复制
MySQL主从复制 主服务器 配置文件目录 mkdir /var/lib/mysql/master/conf.d 数据存储目录 mkdir var/lib/mysql/master/data 配置my ...
- Vue 自动获取最新的Vue文件
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
- vue数组赋值
在使用vue开发移动端项目过程中,统一数组在对多个变量赋值时:希望一个数组的改变不影响另外一个数组,此时可以使用如下方式实现: let arr = [] let a1 = JSON.parse(JSO ...
- HTML5纯Web前端也能开发直播,不用开发服务器(使用face2face)
前段时间转载了某位大神的一篇文章,开发Web版一对一远程直播教室只需30分钟 - 使用face2face网络教室.非常有意思.看起来非常简单,但作为一名前端开发人员来说,还是有难度.因为要开发服务器端 ...
- php 二位数组排序
$member_ship_level 是一个二维数组 $res = array_column($member_ship_level,'integral'); array_multisort($res, ...
- 基于STM32F103ZET6 HC_SR501人体红外感应
这是最后的实验现象,有人走过会一直输出有人,离开范围时则输出没人 开发板 PZ6086L ,HC_SR501模块 这是HC_SR501的示意图,,VCC和GND不再多做介绍,5V供电就行, OUT接口 ...
- go 网络请求篇
---恢复内容开始--- 今天特意找了下go的网络请求篇,get请求是ok的,post请求一直不下来,搜索了下,代码都差不多,无法拿到post数据,先整理一篇,亲测可用. 针对post ,先来说下po ...
- ASP.NET 并发控制
当多个用户试图同时修改数据时,需要建立控制机制来防止一个用户的修改对同时操作的其他用户所作的修改产生不利的影响.处理这种情况的系统叫做“并发控制”. 并发控制的类型 通常,管理数据库中的并发有三种常见 ...
- Apache入门篇(一)之安装部署apache
一.HTTPD特性 (1)高度模块化:core(核心) + modules(模块) = apache(2)动态模块加载DSO机制: Dynamic Shared Object(动态共享对象)(3)MP ...
- SpringBoot-08:SpringBoot采用json的方式实现前后台通用的配置文件
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 一.需求: 本篇博客是最近笔者做的一个项目,已经上线但是还在不断开发,有些页面上的配置,测试服务器和正式服务器 ...