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 ...
随机推荐
- Cookie SameSite属性介绍及其在ASP.NET项目中的应用
一.Cookie SameSite属性介绍 就像大家已经知道的,一旦设置Cookie之后,在Cookie失效之前浏览器会一直将这个Cookie在后续所有的请求中都传回到Server端.我们的系统会利用 ...
- 网维大师重建B盘方法
[操作步骤]操作前先熟悉步骤,以免手忙脚乱.请在人少的时候操作. 1.打开网维大师安装目录,进入barserver\找到barserver.ini打开,找到[PlatformUpdate]字段下的up ...
- vue cli3配置开发环境、测试环境、生产(线上)环境
cli3创建vue项目是精简版的少了build和config这2个文件,所以配置开发环境.测试环境.生产环境的话需要自己创建env文件. 需要注意2点: 1.cli2创建项目生成的config文件里的 ...
- 强化学习之三:双臂赌博机(Two-armed Bandit)
本文是对Arthur Juliani在Medium平台发布的强化学习系列教程的个人中文翻译,该翻译是基于个人分享知识的目的进行的,欢迎交流!(This article is my personal t ...
- vim-0-indent(缩进)
缩进: 参考自http://liuzhijun.iteye.com/blog/1831548,http://blog.csdn.net/chenxiang6891/article/details/41 ...
- Jmeter接口测试之案例实战(十一)
在前面的知识体系中详细的介绍了Jmeter测试工具在接口自动化测试中的基础知识,那么今天更新的文章主要是对昨晚的上课内容做个总结. 首先来看Jmeter测试工具在图片上传中的案例应用.首先结合互联网产 ...
- GitHub 运用实战入门,奶妈级教学
## 前言: 我不会用*官方*的语言告诉你Git 是什么,对此我表示深深得歉意--在我看来像CSDN.博客园.掘金等博客交流平台就是小的“GitHub”,只不过在这里更多的是一些零零散散的笔记或者文章 ...
- Vertica的这些事(十三)——Vertica备份元数据信息
---备份资源池 SELECT 'CREATE RESOURCE POOL ' || name || CASE WHEN memorysize IS NULL THEN ' ' ELSE ' MEMO ...
- ScrollViewer - 可用鼠标拖动滚动的列表框
ScrollViewer添加附加属性: using System; using System.Collections.Generic; using System.Windows; using Syst ...
- wifi无线桥接
考虑到不同路由器配置上或许有细微差别,我此处路由器是水星(牌子)路由器. 首先需要2台路由器,一台已经能够上网,作为主路由器:另一台啥都没有配置,将来用作副路由器,与主路由器桥接. 步骤: 获取主路由 ...