LCA最近公共祖先
不会 准备研究一波!!!
#include<bits/stdc++.h>
const int maxn = ;
using namespace std;
vector<int> g[maxn];
int par[][maxn], dep[maxn], n, m, ml;
void dfs(int v, int p, int d)
{
par[][v] = p;
dep[v] = d;
for (int i = ; i < g[v].size(); ++i){
if (g[v][i] != p) dfs(g[v][i], v, d + );
}
return ;
}
void init(int v)
{
dfs(v, -, );
int sum = ;
while (sum <= n) sum <<= , ++ml;
for (int k = ; k < ml; ++k){
for (int v = ; v <= n; ++v){
if (par[k][v] == -) par[k + ][v] = -;
else par[k + ][v] = par[k][par[k][v]];
}
}
return ;
}
int lca(int u, int v)
{
if (dep[u] > dep[v]) swap(u, v);
for (int k = ; k < ml; ++k){
if (((dep[v] - dep[u]) >> k) & ) v = par[k][v];
}
if (u == v) return u;
for (int k = ml; k >= ; --k){
if (par[k][u] != par[k][v]) u = par[k][u], v = par[k][v];
}
return par[][u];
}
int main()
{
int s, u, v;
scanf("%d %d %d", &n, &m, &s);
int t = n;
while (--t){
scanf("%d %d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
init(s);
while (m--){
scanf("%d %d", &u, &v);
printf("%d\n", lca(u, v));
}
return ;
}
题目 https://www.luogu.org/problemnew/show/P3379
自己写的一个倍增LCA
#include<iostream>
#include<cstring>
//#include<bits/stdc++.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstdio>
#include<map>
#include<set>
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sii(a,b) scanf("%d%d",&a,&b)
#define sll(a,b) scanf("%lld%lld",&a,&b)
#define queues priority_queue
#define mod 998244353
#define mem(a) memset(a,0,sizeof(a));
#define def(a) ((a)&(-a))
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
//priority_queue<int,vector<int >,greater<int > >q;
const ll INF=0x3f3f3f3f;
//const double E=exp(1);
//const double PI=acos(-1);
using namespace std;
int de[];
int lg[];
int f[][];
vector<int>ss[];
void get_lg()
{lg[]=-;
for(int i=;i<=;i++)
lg[i]=lg[i>>]+;
}
void dfs(int p,int fa)
{ de[p]=de[fa]+;
f[p][]=fa;
for(int i=;i<=lg[de[p]]+;i++)
f[p][i]=f[f[p][i-]][i-];
for(int i=;i<ss[p].size();i++)
{ int x=ss[p][i];
if(x!=fa)
{
dfs(x,p);
}
}
}
int LCA(int a,int b)
{ if(de[a]<de[b])swap(a,b);
while(de[a]!=de[b])
{
a=f[a][lg[de[a]-de[b]]];
}
if(a==b)return a;
for(int i=lg[de[a]];i>=;i--)
{
if(f[a][i]!=f[b][i])
a=f[a][i],b=f[b][i];
}
return f[a][];
}
int main()
{ ios::sync_with_stdio(false);
int n,m,s;
scanf("%d%d%d",&n,&m,&s);
for(int i=;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
ss[a].pb(b);
ss[b].pb(a);
}
get_lg();
dfs(s,);
for(int i=;i<=n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",LCA(a,b));
// cout<<LCA(a,b)<<endl;
}
}
又有一个树链剖分求LCA
#include<bits/stdc++.h>
typedef long long ll;
const int maxn=+;
const int INF=0x3f3f3f3f;
using namespace std;
const ll MAX=
int read(){int x=,f=;char s=getchar();for(; s>''||s<''; s=getchar()) if(s=='-') f=-;for(; s>=''&&s<=''; s=getchar()) x=x*+s-'';return x*f;}
vector<int>q[maxn];
int f[maxn];
int d[maxn];
int siz[maxn];
int son[maxn]; int top[maxn];
int id[maxn];
int rk[maxn];
int dfs(int a,int fa)
{
f[a]=fa;
d[a]=d[fa]+;
siz[a]=;
for(int i=; i<q[a].size(); i++)
{
int z=q[a][i];
if(z!=fa)
{
dfs(z,a);
siz[a]+=siz[z];
if(!son[a]||siz[z]>siz[son[a]])
son[a]=z;
}
}
return ;
}
int sum;
void dfs1(int a,int b)
{
top[a]=b;
if(!son[a])
return ;
dfs1(son[a],b);
for(int i=; i<q[a].size(); i++)
{
int z=q[a][i];
if(z!=f[a]&&z!=son[a])
dfs1(z,z);
}
}
int lca(int a,int b)
{
while(top[a]!=top[b])
{
d[top[a]]>d[top[b]]?a=f[top[a]]:b=f[top[b]]; }
return d[a]<d[b]?a:b;
}
int main()
{
ios::sync_with_stdio(false);
int n,m,s;
n=read();m=read();s=read();
for(int i=; i<n; i++)
{
int a,b;
a=read();
b=read();
q[a].pb(b);
q[b].pb(a);
}
dfs(s,);
dfs1(s,s);
while(m--)
{
int a,b;
a=read();
b=read();
cout<<lca(a,b)<<endl;
}
}
LCA最近公共祖先的更多相关文章
- lca 最近公共祖先
http://poj.org/problem?id=1330 #include<cstdio> #include<cstring> #include<algorithm& ...
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)
Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...
- LCA(最近公共祖先)模板
Tarjan版本 /* gyt Live up to every day */ #pragma comment(linker,"/STACK:1024000000,1024000000&qu ...
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...
- LCA近期公共祖先
LCA近期公共祖先 该分析转之:http://kmplayer.iteye.com/blog/604518 1,并查集+dfs 对整个树进行深度优先遍历.并在遍历的过程中不断地把一些眼下可能查询到的而 ...
- LCA 近期公共祖先 小结
LCA 近期公共祖先 小结 以poj 1330为例.对LCA的3种经常使用的算法进行介绍,分别为 1. 离线tarjan 2. 基于倍增法的LCA 3. 基于RMQ的LCA 1. 离线tarjan / ...
- LCA最近公共祖先 ST+RMQ在线算法
对于一类题目,是一棵树或者森林,有多次查询,求2点间的距离,可以用LCA来解决. 这一类的问题有2中解决方法.第一种就是tarjan的离线算法,还有一中是基于ST算法的在线算法.复杂度都是O( ...
- Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】
一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...
- (转)Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)
基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...
- LCA 最近公共祖先 tarjan离线 总结 结合3个例题
在网上找了一些对tarjan算法解释较好的文章 并加入了自己的理解 LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通 ...
随机推荐
- Luogu5283 十二省联考2019异或粽子(trie/可持久化trie+堆)
做前缀异或和,用堆维护一个五元组(x,l,r,p,v),x为区间右端点的值,l~r为区间左端点的范围,p为x在l~r中最大异或和的位置,v为该最大异或和,每次从堆中取出v最大的元素,以p为界将其切成两 ...
- Codeforces484 A. Bits
题目类型:位运算 传送门:>Here< 题意:求区间\([L,R]\)内二进制中1的个数最多的那个数,如果有多解输出最小解 解题思路 想了15min就一遍A了 我们可以贪心地在\(L\)的 ...
- rest framework 序列化
serializers 序列化组件 可以实现很轻松的互相转换,最常用的组件 ,用量最大的组件 源码位置 rest_framework.serializers 源码中需要用到的 rest_fram ...
- [NOI2009]诗人小G(dp + 决策单调性优化)
题意 有一个长度为 \(n\) 的序列 \(A\) 和常数 \(L, P\) ,你需要将它分成若干段,每 \(P\) 一段的代价为 \(| \sum ( A_i ) − L|^P\) ,求最小代价的划 ...
- JSON.stringify() 和 JSON.parse()
stringify()用于从一个对象解析出字符串,如 var obj = {x: 1, y: 2 } console.log(JSON.stringify(obj)) //{"x" ...
- [hashcat]基于字典和暴力破解尝试找到rar3-hp的压缩包密码
1.使用rar2john找到md5 2.基于字典 hashcat -a 0 -m 12500 /root/Desktop/md5.txt /usr/share/wordlists/weakpass.t ...
- jenkins系列之jenkins job
第一步:在 jenkins 左边栏点击 "新建", 输入 job 名称,选择 "构建一个自由风格的软件项目" 一项.点击 "OK" . 第二 ...
- python 爬虫之beautifulsoup(bs4)环境准备
环境准备: bs4安装方法:https://blog.csdn.net/Bibabu135766/article/details/81662981 requests安装方法:https://blog. ...
- 学习Git过程中常用命令的总结
复制远程库git clone git@github.com:Hconly/learngit.git在GitHub上,可以任意Fork开源仓库:自己拥有Fork后的仓库的读写权限:可以推送pull re ...
- HDU 1049(蠕虫爬井 **)
题意是一只虫子在深度为 n 的井中,每分钟向上爬 u 单位,下一分钟会下滑 d 单位,问几分钟能爬出井. 本人是直接模拟的,这篇博客的分析比较好一些,应当学习这种分析问题的思路:http://www. ...