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
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>
#include<vector>
using namespace std;
const int N=1E4+;
bool pre[N];
vector<int >ve[N];
typedef long long ll;
ll bits[];
int depth[N],fa[N][];
void inint(){
bits[]=;
for(int i=;i<=;i++) bits[i]=bits[i-]<<;
}
void dfs(int x,int y){
depth[x]=depth[y]+;
fa[x][]=y;
for(int i=;i<=;i++){
fa[x][i]=fa[fa[x][i-]][i-];
}
for(int i=;i<ve[x].size();i++){
int x1=ve[x][i];
if(x1!=y){
dfs(x1,x);
}
}
}
int lca(int x,int y){
if(depth[x]<depth[y]) swap(x,y);
int dif=depth[x]-depth[y];
for(int i=;i>=;i--){
if(dif>=bits[i]){
x=fa[x][i];
dif-=bits[i];
}
}
if(x==y) return x;
for(int i=;i>=;i--){
if(depth[x]>=bits[i]&&fa[x][i]!=fa[y][i]){
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][];
} int main(){
int t;
inint();
scanf("%d",&t);
while(t--){
memset(pre,,sizeof(pre));
memset(fa,,sizeof(fa));
memset(depth,,sizeof(depth));
int n;
scanf("%d",&n);
int x,y;
for(int i=;i<=n-;i++){
scanf("%d%d",&x,&y);
ve[x].push_back(y);
ve[y].push_back(x);
pre[y]=;
}
int ancestor; for(int i=;i<=n;i++){
if(pre[i]==){
ancestor=i;
break;
}
}
dfs(ancestor,);
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y)); for(int i=;i<=n;i++){
ve[i].clear();
}
}
return ;
}
还可以用 暴力 朴素算法来算
#include<stdio.h>///LCA最近公共祖先查询,朴素算法
#include<string.h>
int fa[]; int deep(int x)///计算x节点深度
{
int cnt=;
while(x)
{
cnt++;
x=fa[x];
}
return cnt;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
memset(fa,,sizeof(fa));///该数组记录每个节点的父亲,根节点父亲为0
int s,f;
scanf("%d",&n);
for(int i=;i<n-;i++){
scanf("%d%d",&f,&s);
fa[s]=f;
} int a,b;
scanf("%d%d",&a,&b);
int x1=deep(a),y1=deep(b);
//只是用深度做了一个判断 取了一个差。
if(x1<y1)///查询的深度若两个节点深度不同,将较深的节点先上移
{
int tt=y1-x1;
while(tt--)
b=fa[b];
}
else if(x1>y1){
int tt=x1-y1;
while(tt--)
a=fa[a];
} while(a!=b)///两个节点深度相同时同时向上寻找父亲,直到父亲相同
a=fa[a],b=fa[b];
printf("%d\n",a);
}
}
LCA Nearest Common Ancestors (很典型的例题)的更多相关文章
- 【POJ】1330 Nearest Common Ancestors ——最近公共祖先(LCA)
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18136 Accept ...
- POJ 1330 Nearest Common Ancestors LCA题解
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 19728 Accept ...
- POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)
POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...
- POJ 1330 Nearest Common Ancestors 倍增算法的LCA
POJ 1330 Nearest Common Ancestors 题意:最近公共祖先的裸题 思路:LCA和ST我们已经很熟悉了,但是这里的f[i][j]却有相似却又不同的含义.f[i][j]表示i节 ...
- POJ 1330 Nearest Common Ancestors(Targin求LCA)
传送门 Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 26612 Ac ...
- POJ - 1330 Nearest Common Ancestors(基础LCA)
POJ - 1330 Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %l ...
- pku 1330 Nearest Common Ancestors LCA离线
pku 1330 Nearest Common Ancestors 题目链接: http://poj.org/problem?id=1330 题目大意: 给定一棵树的边关系,注意是有向边,因为这个WA ...
- poj 1330 Nearest Common Ancestors lca 在线rmq
Nearest Common Ancestors Description A rooted tree is a well-known data structure in computer scienc ...
- poj 1330 Nearest Common Ancestors(LCA 基于二分搜索+st&rmq的LCA)
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 30147 Accept ...
随机推荐
- 太赞了!阿里几位工程师重写了 《Java 并发编程》
事情是这样的,前些日子和得知一个读者在准备阿里的面试,我蛮有兴趣的跟他聊了起来,随着话题越来越深入,我发现这位读者有意思,他和几位阿里的工程师之前编写了一本 concurrent.redspider. ...
- eNSP上NAT的配置
NAT介绍: 早在20世纪90年代初,有关RFC文档就提出了IP地址耗尽的可能性.IPv6技术的提出虽然可以从根本上解决地址短缺的问题,但是也无法立刻替换现有成熟且广泛应用的IPv4网络.既然不能 立 ...
- 什么是CPU load
最近经常收到告警,CPU load大于阈值告警.查看系统的CPU是12核,告警阈值设置的是8.对于CPU load一直有个模糊的概念,具体是什么意思还真搞不明白,趁这个机会好好搞搞究竟. 1.查看CP ...
- effective-java学习笔记---优先使用泛型方法30
泛型类型比需要在客户端代码中强制转换的类型更安全,更易于使用. 当你设计新的类型时,确保它们可以在没有这种强制转换的情况下使用. 这通常意味着使类型泛型化. 如果你有任何现有的类型,应该是泛型的但实际 ...
- 累加数的贡献 CodeForces - 1213D2
题意: 第一行输入n,k,表示有n个数,可以进行整除2操作,要是数组有k个相等的数,最少需要几次操作. 思路: 用一个数组记录每一个数出现的次数,如果一开始大于等于k,直接输出0,否则对这n个数进行从 ...
- Jenkins打造多分支流水线指南
overview: 多分支工作流程带来了以下几个关键能力: 在代码仓库中,每个新分支都有自己单独的工作流水线(job). 每个工作流水线都记录了对应分支的构建和变更历史. 可以自定义设置流水线随着分支 ...
- [vijos1782]借教室<线段树>
题目链接:https://vijos.org/p/1782 题意:一个区间1,n.m次操作,每次操作让l,r区间值减去d,当有任何一个值小于0就输出当前是第几个操作 这道题其实是没有什么难度的,是 ...
- MATLAB 排序、拟合
一.数据排序整合 1.随机生成的数,从小到大排序 clear rand('seed',1)%设置随机种子,确保随机数一样 edge_range=unifrnd (1, 10, 1, 10) edge_ ...
- Java常用类__装箱/拆箱
以下是常用的各两种方法(各类提供了构造方法,静态方法) 一.基本数据类型 转化为 包装类(装箱) 例:int i=10: Integer num=i;//num=10 二.包装类 转化为 基本数据类 ...
- 论redis的内存占用
目前大部分成程序员都将一些数据放入到了缓存(redis)中,但是你是否对这个redis内存占用了解呢?下面我们就来说一下redis的内存最优使用: 1.我们首先来介绍一下我们在存入大量数据到redis ...