Lca 之倍增算法
引入:
lca:
倍增:
贴上自己yy的代码:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int N = 4e4;
const int M = 4e5;
using namespace std;
int h[N],cnt,gra[N][],dep[N];
int maxn[N][],n,m;
struct path{
int next,to;
int dis;
}e[M];
void add(int u,int v,int dis){
e[++cnt].to = v;
e[cnt].next = h[u];
e[cnt].dis = dis;
h[u] = cnt;
}
void dfs(int u,int pre){
for(int i = h[u];i;i = e[i].next){
int v = e[i].to;
if(v == pre)continue;
gra[v][] = u;//处理出每个点的直接父亲
maxn[v][] = e[i].dis;//处理出每个点到直接父亲的距离
dep[v] = dep[u] + ;
dfs(v,u);
}
}
int LCA(int x,int y){
if(dep[x] < dep[y])swap(x,y);
int flag = false;
int log;
for(log = ;( << log) <= dep[x];log++);log--;
int ans = ;
for(int i = log;i >= ;i--)
if(dep[x] - ( << i) >= dep[y]){
ans = max(ans,maxn[x][i]);
x = gra[x][i];
}//把x向上移到和y相同高度
if(x == y)return ans;//如果y就是lca 直接跳出
for(int i = log;i >= ;i--){
if(gra[x][i] && gra[y][i] != gra[x][i]){
ans = max(ans,maxn[x][i]);x = gra[x][i];
ans = max(ans,maxn[y][i]);y = gra[y][i];
}
}//把x 和 y同时向上移,如果相同,即找到lca
if(gra[x][])ans = max(ans,maxn[x][]);
if(gra[y][])ans = max(ans,maxn[y][]);
if(!gra[x][] && x != y)return -;//如果移到根节点且x != y即x,y不在一颗树上返回-1
return ans;
}
void getMap(){
scanf("%d %d",&m,&n);
int a,b,z;
for(int i = ;i <= n;i++){
scanf("%d %d %d",&a,&b,&z);
add(a,b,z);
add(b,a,z);
}
for(int i = ;i <= m;i++){
if(!dep[i]){
dep[i] = ;
dfs(i,-);
}
}
for(int j = ;( << j) <= m;j++)
for(int i = ;i <= m;i++)
if(gra[i][j - ]){
int a = gra[i][j - ];
gra[i][j] = gra[a][j - ];
maxn[i][j] = max(maxn[i][j - ],maxn[a][j - ]);
}//处理出每个点1 - 2^k的父亲,和路上最大边权;
}
int main(){
getMap();
return ;
}
Lca 之倍增算法的更多相关文章
- LCA的倍增算法
LCA,即树上两点之间的公共祖先,求这样一个公共祖先有很多种方法: 暴力向上:O(n) 每次将深度大的点往上移动,直至二者相遇 树剖:O(logn) 在O(2n)预处理重链之后,每次就将深度大的沿重链 ...
- 关于树论【LCA树上倍增算法】
补了一发LCA,表示这东西表面上好像简单,但是细节真挺多. 我学的是树上倍增,倍增思想很有趣~~(爸爸的爸爸叫奶奶.偶不,爷爷)有一个跟st表非常类似的东西,f[i][j]表示j的第2^i的祖先,就是 ...
- LCA(最近公共祖先)之倍增算法
概述 对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 如图,3和5的最近公共祖先是1,5和2的最近公共祖先是4 在本篇中我们先介 ...
- LCA倍增算法
LCA 算法是一个技巧性很强的算法. 十分感谢月老提供的模板. 这里我实现LCA是通过倍增,其实就是二进制优化. 任何一个数都可以有2的阶数实现 例如16可以由1 2 4 8组合得到 5可以由1 2 ...
- 最近公共祖先 LCA 倍增算法
树上倍增求LCA LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 ...
- 关于LCA的倍增解法的笔记
emmmmm近日刚刚学习了LCA的倍增做法,写一篇BLOG来加强一下印象w 首先 何为LCA? LCA“光辉”是印度斯坦航空公司(HAL)为满足印度空军需要研制的单座单发轻型全天候超音速战斗攻击机,主 ...
- [模板]LCA的倍增求法解析
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 【一个蒟蒻的挣扎】LCA (倍增)
#include<cstdio> #include<iostream> #include<cstring> using namespace std; struct ...
- LCA树上倍增求法
1.LCA LCA就是最近公共祖先(Least common ancestor),x,y的LCA记为z=LCA(x,y),满足z是x,y的公共祖先中深度最大的那一个(即离他们最近的那一个)qwq 2. ...
随机推荐
- centos6上安装mysql8.0版本
本博客是采用yum源的方式安装,非常的方便和快捷.(redhat 与centos7 等操作系统都可以采用此方法,步骤大体一致) mysql官网地址: https://dev.mysql.com 开 ...
- centos 更换yum源 (解决下载慢的问题)
先看有没有安装wget wget -V 如果没有执行 yum -y install wget 进行安装 然后进行配置的备份 mv /etc/yum.repos.d/CentO ...
- uva1609 Foul Play
思维 创造条件使一轮比赛之后仍满足1号打败至少一半,并剩下至少一个t' 紫书上的思路很清晰阶段1,3保证黑色至少消灭1半 #include<cstdio> #include<vect ...
- iview table的render()函数基本的用法
render:(h,params) => { return h(" 定义的元素 ",{ 元素的性质 }," 元素的内容"/[元素的内容]) }
- python之str (字符型)
用途: 存储少量的数据,+ *int 切片, 其他操作方法 切片还是对其进行任何操作,获取的内容全部是strl类型 存储数据单一 格式: 在python中用引号引起来的就是字符串 '今天吃了没?' 1 ...
- 【2018 CCPC网络赛】1003 - 费马小定理
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6440 这题主要是理解题意: 题意:定义一个加法和乘法,使得 (m+n)p = mp+np; 其中给定 ...
- C/C++连接MySQL数据库执行查询
1. 简介: 使用C/C++连接MySQL数据库执行增删改查操作,基本就是围绕以下两个文件展开: mysql.h(此头文件一般在MySQL的include文件夹内,如 D:\MySQL\mysql-5 ...
- 实验楼Python学习记录_挑战字符串操作
自我学习记录 Python3 挑战实验 -- 字符串操作 目标 在/home/shiyanlou/Code创建一个 名为 FindDigits.py 的Python 脚本,请读取一串字符串并且把其中所 ...
- SpringCloud源码地址
SpringCloud实战源代码 https://github.com/springcloud/spring-cloud-code.git
- hdu3376 Matrix Again
最大费用最大流 咋写?取个相反数就可以了-- #include <iostream> #include <cstring> #include <cstdio> #i ...