最近公共祖先(LCA)模板

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

 

模板:时间复杂度nlogn

 

#include<iostream>
#include<cstdio>
using namespace std;
struct yyy{
       int t,
       nex;
}e[2 * 500001];
int deepth[500001], fa[500001][22], lg[500001], head[500001];
int tot;
void add(int x, int y) //邻接表存树
{
       e[++tot].t = y;
       e[tot].nex = head[x];
       head[x] = tot;
}
void dfs(int f, int fath)
{
       deepth[f] = deepth[fath] + 1;
       fa[f][0] = fath;
       for (int i = 1; (1 << i) <= deepth[f]; i++)
              fa[f][i] = fa[fa[f][i - 1]][i - 1];
       for (int i = head[f]; i; i = e[i].nex)
       if (e[i].t != fath)
              dfs(e[i].t, f);
}
int lca(int x, int y)
{
       if (deepth[x]<deepth[y])
              swap(x, y);
       while (deepth[x]>deepth[y])
              x = fa[x][lg[deepth[x] - deepth[y]] - 1];
       if (x == y)
              return x;
       for (int k = lg[deepth[x]]; k >= 0; k--)
       if (fa[x][k] != fa[y][k])
              x = fa[x][k], y = fa[y][k];
       return fa[x][0];
}
int n, m, s;//n节点,m查询,s边数
void init()
{
       scanf("%d%d%d", &n, &m, &s);
       for (int i = 1; i <= n - 1; i++)
       {
              int x, y;  scanf("%d%d", &x, &y);
              add(x, y); add(y, x);
       }
       dfs(s, 0);
       for (int i = 1; i <= n; i++)
              lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
}
 
int main()
{
       init();
       for (int i = 1; i <= m; i++)
       {
              int x, y;  scanf("%d%d", &x, &y);
              printf("%d\n", lca(x, y));
       }
 
       return 0;
}

 

转载于:https://www.cnblogs.com/ALINGMAOMAO/p/9643481.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101426.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Laravel数据库操作的三种方式

    Laravel数据库操作的三种方式

    2021年10月26日
    40
  • 矩阵特征值和特征向量详细计算过程(转载)_矩阵特征值的详细求法

    矩阵特征值和特征向量详细计算过程(转载)_矩阵特征值的详细求法1.矩阵特征值和特征向量定义        A为n阶矩阵,若数λ和n维非0列向量x满足Ax=λx,那么数λ称为A的特征值,x称为A的对应于特征值λ的特征向量。式Ax=λx也可写成(A-λE)x=0,并且|λE-A|叫做A的特征多项式。当特征多项式等于0的时候,称为A的特征方程,特征方程是一个齐次线性方程组,求解特征值的过程其实就是求解特征方程的解。 计算:A的特征值和特征向量。计算行列式得化简…

    2025年8月21日
    5
  • 更新源metaspolit报错GPG Error「建议收藏」

    更新源metaspolit报错GPG Error「建议收藏」通过msfupdate无法更新到最新版本,需首先更新系统源:)更新系统源报错,提示metaspolitGPGerror:解决方案:输入以下两条命令1、sudoecho‘debhttp://apt.metasploit.com/lucidmain’>/etc/apt/sources.list.d/metasploit-framework.list2、sudowge…

    2022年10月9日
    11
  • freemaker判断空_python条件语句举例

    freemaker判断空_python条件语句举例if…else…&lt;#if condition&gt;  …&lt;#elseif condition2&gt;  …&lt;#elseif condition3&gt;  …&lt;#else&gt;  …&lt;/#if&gt;只有一个if的情况:&lt;#if x = 1&gt;  x is 1&lt;/#if&gt; 包含elseif的情况:

    2025年6月8日
    5
  • Hybrid开发框架一、Weex

    Hybrid开发框架一、Weex前言最近开始试水Weex开发,使用这么长一段时间,感觉写Weex还是非常方便的。作为一个Android开发,免不了要追查一下weex的sdk源码。今天,就以WeexSDKforAndroid为例,分析SDK的认识WeexSDK源码https://github.com/alibaba/weex/tree/dev/android整体分析下拉,按照js文件的渲染过程,绘制出了下面…

    2022年9月22日
    6
  • MYSQL数据类型_c语言数据类型详解

    MYSQL数据类型_c语言数据类型详解上一篇博客中我们学习了MySQL的基础知识以及表结构的相关操作,知道了MySQL中常用的数据类型有数值型、字符串型、日期时间类型下面我们来使用一下这些数据类型。数值类型首先数值类型分为整型和浮点型我们先来看看整型整型首先创建一个表CREATETABLEint_db(aTINYINT,bSMALLINT,cMIDDLEINT,dINT,eB…

    2026年2月5日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号