P3379 【模板】最近公共祖先(LCA)

题目描述

如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。

输入输出格式

输入格式:

第一行包含三个正整数N、M、S,分别表示树的结点个数、询问的个数和树根结点的序号。

接下来N-1行每行包含两个正整数x、y,表示x结点和y结点之间有一条直接连接的边(数据保证可以构成树)。

接下来M行每行包含两个正整数a、b,表示询问a结点和b结点的最近公共祖先。

输出格式:

输出包含M行,每行包含一个正整数,依次为每一个询问的结果。

输入输出样例

输入样例#1:

5 5 4
3 1
2 4
5 1
1 4
2 4
3 2
3 5
1 2
4 5
输出样例#1:

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)的更多相关文章

  1. [模板] 最近公共祖先/lca

    简介 最近公共祖先 \(lca(a,b)\) 指的是a到根的路径和b到n的路径的深度最大的公共点. 定理. 以 \(r\) 为根的树上的路径 \((a,b) = (r,a) + (r,b) - 2 * ...

  2. Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集)

    Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集) Description sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为 ...

  3. POJ 1470 Closest Common Ancestors(最近公共祖先 LCA)

    POJ 1470 Closest Common Ancestors(最近公共祖先 LCA) Description Write a program that takes as input a root ...

  4. POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)

    POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...

  5. 【lhyaaa】最近公共祖先LCA——倍增!!!

    高级的算法——倍增!!! 根据LCA的定义,我们可以知道假如有两个节点x和y,则LCA(x,y)是 x 到根的路 径与 y 到根的路径的交汇点,同时也是 x 和 y 之间所有路径中深度最小的节 点,所 ...

  6. 【洛谷 p3379】模板-最近公共祖先(图论--倍增算法求LCA)

    题目:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 解法:倍增. 1 #include<cstdio> 2 #include<cstdlib> 3 #include ...

  7. 最近公共祖先(LCA)模板

    以下转自:https://www.cnblogs.com/JVxie/p/4854719.html 首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖 ...

  8. HDU 2586 How far away ?(LCA模板 近期公共祖先啊)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the vi ...

  9. luogu3379 【模板】最近公共祖先(LCA) 倍增法

    题目大意:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 整体步骤:1.使两个点深度相同:2.使两个点相同. 这两个步骤都可用倍增法进行优化.定义每个节点的Elder[i]为该节点的2^k( ...

  10. 最近公共祖先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 ...

随机推荐

  1. Allocate exception for servlet ValidateUsernameServlet 异常

    如果eclipse无法对类文件进行编译那么运行时就会发生 Allocate exception for servlet ValidateUsernameServlet 异常,说找不到类.

  2. ZOJ Monthly, January 2019 Little Sub and his Geometry Problem 【推导 + 双指针】

    传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5861 Little Sub and his Geometry Prob ...

  3. MyBatis(10)逆向工程

    什么是逆向工程? 在学习的过程中会发现,需要我们写大量的sql语句 此时mybaatis官方为我们提供逆向工程可以针对单表自动生成的mybatis执行所需要的代码     使用方法:    MyBat ...

  4. 查找连接过的USB存储设备

    gp "HKLM:\SYSTEM\CurrentControlSet\Enum\USBSTOR\*\*"|select friendlyname,CompatibleIDs,mfg ...

  5. HDU 1250 Hat's Fibonacci(大数相加)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1250 Hat's Fibonacci Time Limit: 2000/1000 MS (Java/Ot ...

  6. JQuery手写一个简单的分页

    效果图: 大概思路:使用ul进行初始布局,每一次点击事件改变li里的值.完整的代码在gitup上:https://github.com/anxizhihai/Paging.gitcss部分: html ...

  7. 【微信开发】LINUX-windows下用navicat远程链接虚拟机Linux下MySQL数据库

    今天想用navicat远程连接虚拟机中的MySQL数据库,一直连不上,在网上搜索了一下,发现原因是MySQL对远程用户登陆的授权问题.   MySQL登陆:mysql -h主机地址 -u用户名-p用户 ...

  8. 使用py2exe将python程序打包成exe程序

    近日帮朋友写了个python小程序,从互联网上抓取一些需要的文章到本地.为了运行方便,希望能转换成exe程序在windows下定期执行.从百度上找了些文章,发现py2exe的应用比较多,遂使用之. 1 ...

  9. ORCLE10安装常见配置问题-oui.exe停止工作

    其实这是一个在安装过程中很常见的问题,之前小编说过关于甲骨文的软件用起来都很强大,但是大腕出厂,出场费是很高的,就像甲骨文的软件使用的话对于他的安装和配置的换将也是很挑剔的,出现这个问题就是因为安装文 ...

  10. hashMap 和 linkedHashMap 的区别和联系

    直接举例说明. 运行如下例子程序 mport java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; ...