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 ...
随机推荐
- Android课程设计——博学谷1.0
本文讲述了如何应用大三下学期智能移动终端开发技术课程所学知识,完成包含服务器端.客户端程序的应用——博学谷登录模块的开发,结合java语言基本知识,例如:字符串.列表.类.数据库读写等,设计.实现一个 ...
- 面试刷题17:线程两次start()会发生什么?
线程是并发编程的基础元素,是系统调度的最小单元,现代的jvm直接对应了内核线程.为了降低并发编程的门槛,go语言引入了协程. 你好,我是李福春,我在准备面试,今天的题目是? 一个线程两次调用start ...
- 基于树莓派与YOLOv3模型的人体目标检测小车(一)
项目介绍: 本科毕业选的深度学习的毕设,一开始只是学习了一下YOLOv3模型, 按照作者的指示在官网上下载下来权重,配好环境跑出来Demo,后来想着只是跑模型会不会太单薄,于是想了能不能做出来个比较实 ...
- Rasa Stack:创建支持上下文的人工智能助理和聊天机器人教程
相关概念 Rasa Stack 是一组开放源码机器学习工具,供开发人员创建支持上下文的人工智能助理和聊天机器人: • Core = 聊天机器人框架包含基于机器学习的对话管理 • NLU = 用于自然语 ...
- BP神经网络及异或实现
BP神经网络是最简单的神经网络模型了,三层能够模拟非线性函数效果. 难点: 如何确定初始化参数? 如何确定隐含层节点数量? 迭代多少次?如何更快收敛? 如何获得全局最优解? ''' neural ne ...
- IOS 空字符串报错 解决办法
NSScanner: nil string argument NSScanner: nil string argument libc++abi.dylib: terminate_handler un ...
- Python第十二章-多进程和多线程01-多进程
多进程和多线程 一.进程 1.1 进程的引入 现实生活中,有很多的场景中的事情是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的:试想,如果把唱歌和跳舞这2件事情分开依次 ...
- 双连通分量 Road Construction POJ - 3352
@[双连通分量] 题意: 有一个 n 个点 m 条边的无向图,问至少添加几条边,能让该图任意缺少一条边后还能相互连通. 双连通分量定义: 在无向连通图中,如果删除该图的任何一个结点都不能改变该图的连通 ...
- MATLAB 文件读取(3)
1.gps ,数值格式的读取 clear all test=importdata('2017- 9-27- 8-26-51.txt'); [r,c]=size(test.data);%row行,col ...
- vulnhub~Djinn:2
这道题挺难的,和Djinn:1相比,正如作者所言,有许多相似的地方.仍然开放着端口 可以看到5个端口开放着,1337是web端口,这里面如djinn1一样,write your wish,但是send ...