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

解法:倍增。

 1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 using namespace std;
6 #define N 500010
7 #define D 20
8
9 int n,m,root,len=0;
10 int last[N],fa[N][D],dep[N];
11 struct edge{int x,y,next;}a[2*N];
12
13 void ins(int x,int y)
14 {
15 a[++len].x=x,a[len].y=y;
16 a[len].next=last[x],last[x]=len;
17 }
18 void build(int x,int f)
19 {
20 fa[x][0]=f, dep[x]=dep[f]+1;
21 for (int i=1;i<=D && (1<<i)<=dep[x];i++)
22 fa[x][i]=fa[fa[x][i-1]][i-1];
23 for (int i=last[x];i!=-1;i=a[i].next)
24 if (a[i].y!=f) build(a[i].y,x);
25 }
26 int LCA(int x,int y)
27 {
28 if (dep[x]<dep[y]) {int t;t=x,x=y,y=t;}
29 if (dep[x]!=dep[y])
30 for (int i=D;i>=0;i--)
31 if (dep[x]>=(1<<i)+dep[y]) x=fa[x][i];
32 if (x==y) return x;
33 for (int i=D;i>=0;i--)
34 if (dep[x]>=(1<<i) && fa[x][i]!=fa[y][i])
35 x=fa[x][i],y=fa[y][i];
36 return fa[x][0];
37 }
38 int main()
39 {
40 scanf("%d%d%d",&n,&m,&root);
41 int x,y;
42 memset(last,-1,sizeof(last));
43 for (int i=1;i<n;i++)
44 {
45 scanf("%d%d",&x,&y);
46 ins(x,y),ins(y,x);
47 }
48 dep[0]=0, build(root,0);//由于是0,x,y之间的最大距离就是fa[x][i],(1<<i)<=dep[x]-dep[y]
49 while (m--)
50 {
51 scanf("%d%d",&x,&y);
52 printf("%d\n",LCA(x,y));
53 }
54 return 0;
55 }

【洛谷 p3379】模板-最近公共祖先(图论--倍增算法求LCA)的更多相关文章

  1. caioj 1236 最近公共祖先 树倍增算法模版 倍增

    [题目链接:http://caioj.cn/problem.php?id=1236][40eebe4d] 代码:(时间复杂度:nlogn) #include <iostream> #inc ...

  2. 洛谷.3809.[模板]后缀排序(后缀数组 倍增) & 学习笔记

    题目链接 //输出ht见UOJ.35 #include<cstdio> #include<cstring> #include<algorithm> const in ...

  3. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  4. 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)

    洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...

  5. 倍增法求lca(最近公共祖先)

    倍增法求lca(最近公共祖先) 基本上每篇博客都会有参考文章,一是弥补不足,二是这本身也是我学习过程中找到的觉得好的资料 思路: 大致上算法的思路是这样发展来的. 想到求两个结点的最小公共祖先,我们可 ...

  6. P5836 [USACO19DEC]Milk Visits S 从并查集到LCA(最近公共祖先) Tarjan算法 (初级)

    为什么以它为例,因为这个最水,LCA唯一黄题. 首先做两道并查集的练习(估计已经忘光了).简单来说并查集就是认爸爸找爸爸的算法.先根据线索理认爸爸,然后查询阶段如果发现他们的爸爸相同,那就是联通一家的 ...

  7. 洛谷P3379 【模板】最近公共祖先(LCA)

    P3379 [模板]最近公共祖先(LCA) 152通过 532提交 题目提供者HansBug 标签 难度普及+/提高 提交  讨论  题解 最新讨论 为什么还是超时.... 倍增怎么70!!题解好像有 ...

  8. 洛谷P3379 【模板】最近公共祖先(LCA)(dfs序+倍增)

    P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...

  9. 洛谷——P3379 【模板】最近公共祖先(LCA)

    P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...

随机推荐

  1. Java 实现简单的 Socket 通信

    Java socket 封装了传输层的实现细节,开发人员可以基于 socket 实现应用层.本文介绍了 Java socket 简单用法. 1. 传输层协议 传输层包含了两种协议,分别是 TCP (T ...

  2. 路由器开启远程控制(ssh或telent)

    • 远程控制        ○ 开启远程控制            § conf t             § line vty 0 4                □ 0 4 意思是最多允许5个 ...

  3. Go从入门到放弃(笔记存档)

    前言 考虑到印象笔记以后不续费了,这里转存到博客园一份 因内容是自己写的笔记, 未作任何润色, 所以看着很精简, 请见谅 查看官方文档 在新的go安装包中,为了减小体积默认去除了go doc 安装go ...

  4. 【C++】《C++ Primer 》第十二章

    第十二章 动态内存 目前为止,所使用的对象都有着严格定义的生存期. 全局对象在程序启动时分配,在程序结束时销毁.局部自动对象在进入其定义所在的程序块时被创建,在离开块时销毁.局部static对象在第一 ...

  5. 基于SVM的字母验证码识别

    基于SVM的字母验证码识别 摘要 本文研究的问题是包含数字和字母的字符验证码的识别.我们采用的是传统的字符分割识别方法,首先将图像中的字符分割出来,然后再对单字符进行识别.首先通过图像的初步去噪.滤波 ...

  6. appium元素识别方式实战

    github代码::  https://github.com/w550856163/App_Demo.git  tag: V1.1 Appium Inspector定位工具界面介绍:  Selecte ...

  7. Ubuntu安装Vivado

    Step1 安装必要的库文件: sudo apt install libncurses5 build-essential openjdk-11-jdk Step2 进入vivado的安装文件夹 sud ...

  8. [CPP] STL 简介

    STL 即标准模板库(Standard Template Library),是 C++ 标准库的一部分,里面包含了一些模板化的通用的数据结构和算法.STL 基于模版的实现,因此能够支持自定义的数据结构 ...

  9. React 入门-redux 和 react-redux

    React 将页面元素拆分成组件,通过组装展示数据.组件又有无状态和有状态之分,所谓状态,可以简单的认为是组件要展示的数据.React 有个特性或者说是限制单向数据流,组件的状态数据只能在组件内部修改 ...

  10. kettle数据质量统计

    1.利用Kettle的"分组","JavaScript代码","字段选择"组件,实现数据质量统计.2.熟练掌握"JavaScrip ...