P3379 【模板】最近公共祖先(LCA)
P3379 【模板】最近公共祖先(LCA)
题目描述
如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。
输入输出格式
输入格式:
第一行包含三个正整数N、M、S,分别表示树的结点个数、询问的个数和树根结点的序号。
接下来N-1行每行包含两个正整数x、y,表示x结点和y结点之间有一条直接连接的边(数据保证可以构成树)。
接下来M行每行包含两个正整数a、b,表示询问a结点和b结点的最近公共祖先。
输出格式:
输出包含M行,每行包含一个正整数,依次为每一个询问的结果。
输入输出样例
5 5 4
3 1
2 4
5 1
1 4
2 4
3 2
3 5
1 2
4 5
4
4
1
4
4
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=10,M<=10
对于70%的数据:N<=10000,M<=10000
对于100%的数据:N<=500000,M<=500000
样例说明:
该树结构如下:

第一次询问:2、4的最近公共祖先,故为4。
第二次询问:3、2的最近公共祖先,故为4。
第三次询问:3、5的最近公共祖先,故为1。
第四次询问:1、2的最近公共祖先,故为4。
第五次询问:4、5的最近公共祖先,故为4。
故输出依次为4、4、1、4、4。
#include<iostream>
#include<cstdio> using namespace std; const int N = ; int n,m,root,ans,cnt;
int head[N];
int deth[N];
int f[N][];
bool vis[N];
struct Edge{
int to,nxt;
}e[N<<]; int Read()
{
int x=,f=;
char c=getchar();
while(c>''||c<'') {if(c=='-') f=-;c=getchar();}
while(c>=''&&c<='') {x=x*+c-''; c=getchar();}
return x*f;
} void add(int a,int b)
{
++cnt;
e[cnt].to = b;
e[cnt].nxt = head[a];
head[a] = cnt;
} void dfs(int a)
{
vis[a] = true;
for(int i=;i<=;i++)
{
if(deth[a] < (<<i)) break;
f[a][i] = f[f[a][i-]][i-];
}
for(int i=head[a];i;i=e[i].nxt)
{
int now = e[i].to;
if(!vis[now])
{
deth[now] = deth[a]+;
f[now][]=a;
dfs(now);
}
}
} int lca(int u,int v)
{
if(deth[u] < deth[v])swap(u,v);
int d = deth[u] - deth[v];
for (int i=; i<; i++) //值得注意的是,这里需要从零枚举
{
if ( (<<i) & d)//一个判断,模拟一下就会很清晰
u = f[u][i];
}
if (u==v) return u;
for (int i=; i>=; i--)
{
if (f[u][i]!=f[v][i]) //跳2^j步不一样,就跳,否则不跳
{
u = f[u][i];
v = f[v][i];
}
}
u = f[u][]; //上述过程做完,两点都在LCA下一层,所以走一步即可
return u;
} int main()
{
int x,y;
n=Read();
m=Read();
root=Read();
for(int i=;i<n;i++)
{
x=Read();
y=Read();
add(x,y);
add(y,x);
}
deth[root] = ;
dfs(root);
while(m--)
{
x=Read();
y=Read();
printf("%d\n",lca(x,y));
}
return ;
}
P3379 【模板】最近公共祖先(LCA)的更多相关文章
- [模板] 最近公共祖先/lca
简介 最近公共祖先 \(lca(a,b)\) 指的是a到根的路径和b到n的路径的深度最大的公共点. 定理. 以 \(r\) 为根的树上的路径 \((a,b) = (r,a) + (r,b) - 2 * ...
- Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集)
Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集) Description sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为 ...
- POJ 1470 Closest Common Ancestors(最近公共祖先 LCA)
POJ 1470 Closest Common Ancestors(最近公共祖先 LCA) Description Write a program that takes as input a root ...
- POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)
POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...
- 【lhyaaa】最近公共祖先LCA——倍增!!!
高级的算法——倍增!!! 根据LCA的定义,我们可以知道假如有两个节点x和y,则LCA(x,y)是 x 到根的路 径与 y 到根的路径的交汇点,同时也是 x 和 y 之间所有路径中深度最小的节 点,所 ...
- 【洛谷 p3379】模板-最近公共祖先(图论--倍增算法求LCA)
题目:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 解法:倍增. 1 #include<cstdio> 2 #include<cstdlib> 3 #include ...
- 最近公共祖先(LCA)模板
以下转自:https://www.cnblogs.com/JVxie/p/4854719.html 首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖 ...
- HDU 2586 How far away ?(LCA模板 近期公共祖先啊)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the vi ...
- luogu3379 【模板】最近公共祖先(LCA) 倍增法
题目大意:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 整体步骤:1.使两个点深度相同:2.使两个点相同. 这两个步骤都可用倍增法进行优化.定义每个节点的Elder[i]为该节点的2^k( ...
- 最近公共祖先lca模板
void dfs(int x,int root){//预处理fa和dep数组 fa[x][0]=root; dep[x]=dep[root]+1; for(int i=1;(1<<i)&l ...
随机推荐
- ES6-模块导入导出
基本用法 命名导出(named exports) 可以直接在任何变量或者函数前面加上一个 export 关键字,就可以将它导出. 例如: export const sqrt = Math.sqrt; ...
- nginx里配置跨域
发布于 881天前 作者 wendal 1404 次浏览 复制 上一个帖子 下一个帖子 标签: nginx 跨域 if ($request_method = OPTIONS ) { add ...
- Redis的Windows端开发连接Linux端以及相应的代码实现
在Windows端开发连接需要进行配置文件的配置: 在redis.conf配置文件中 将protected-mode yes,修改为protected-mode no:不保护redis # By de ...
- 从零开始学习CocoaPods安装和使用
从零开始学习CocoaPods安装和使用 转载: Code4App原创:http://code4app.com/article/cocoapods-install-usage http://m.i ...
- ASP.NET教程
1.ASP.NET是一个使用Html Css JavaScript和服务器脚本创建网页和网站的开发框架 2.ASP.NET支持三种开发模式:WebPages(Web页面).MVC(Model View ...
- 【Cmd命令行】基础—findstr与for循环
Findstr命令 findstr是Window系统自带的命令,用途是查找指定的一个或多个文件文件中包含(或通过参数 /V来控制不包含)某些特定字符串的行,并将该行完整的信息打印出来,或者打印查询字符 ...
- Java日期类题目
每类题都有各种各样解决的方式,大家随意发散 分析以下需求,并用代码实现 1.已知日期字符串:"2015-10-20",将该日期字符串转换为日期对象 2.将(1)中的日期对象转换为日 ...
- 如何理解低耦合AND高内聚?[转]
1.高内聚 首先我们来看看内聚的含义:软件含义上的内聚其实是从化学中的分子的内聚演变过来的,化学中的分子间的作用力,作用力强则表现为内聚程度高.在软件中内聚程度的高低,标识着软件设计的好坏. 我们在进 ...
- MyBatis之properties配置
这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递.例如: <properties resource=" ...
- Drbd双机环境安装配置
一.环境准备 1) 操作系统:ubuntu-14.04.1 x64 2) Ubuntu1 192.168.5.179 /dev/sdb1 主节点 Ubuntu2 192.168.5.178 /dev/ ...