洛谷P3379

注意:不能与LCA搞混(打久了就会发现两个还是有很大区别的)

   位运算一定要加括号!

   for循环从0到logn还是从logn到0看当前的状态更适合哪种

   第53行预处理一定要注意!(因为没有下标为-1的数组)

   第34行也要注意如何判断当前是否跳点(不需要麻烦的位运算,因为如果能跳,dep[y]自然就会变,如果不跳,dep[y]又不变,每次与(dep[y]-dep[x])进行比较,不影响dep[x]与dep[y]的值;

 #include<bits/stdc++.h>
using namespace std;
#define man 500010
inline int read()
{ int x=;bool f=;
char ch=getchar();
while(ch<''||ch>''){f=(ch==);ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+(ch^);ch=getchar();}
return f?(~x+):x;
}
int dep[man],f[man][];
int n,m,logn,root;
int head[man<<],num=;
struct edeg
{ int next,to;}e[man<<];
inline void add(int from,int to)
{ e[++num].next=head[from];
e[num].to=to;
head[from]=num;
}
void dfs(int u,int fa,int depth)
{ f[u][]=fa;
dep[u]=depth;
for(int i=head[u];i;i=e[i].next)
{ int to=e[i].to;
if(to==fa) continue;
dfs(to,u,depth+);
}
return ;
}
inline int LCA(int x,int y)
{ if(dep[x]>dep[y]) swap(x,y);
for(int i=;i<logn;i++)
if(((dep[y]-dep[x])>>i)&) y=f[y][i];
if(x==y) return x;
for(int i=logn;i>=;i--)
{ if(f[x][i]!=f[y][i])
{ x=f[x][i];y=f[y][i];
}
}
return f[x][];
}
int main()
{ n=read(),m=read(),root=read();
logn=(int)(log(n)/log(2.0))+;
for(int i=;i<n;i++)
{ int u=read(),v=read();
add(u,v);add(v,u);
}
dfs(root,-,);
for(int j=;j<logn;j++)
for(int i=;i<=n;i++)
if(f[i][j]<) f[i][j+]=-;
else f[i][j+]=f[f[i][j]][j];
for(int i=;i<=m;i++)
{ int x=read(),y=read();
printf("%d\n",LCA(x,y));
}
return ;
}

 LCA使用BFS应该会快一点吧。。。

 #include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
using namespace std;
#define man 500005
int n,m,root;
int head[man<<],num=;
inline int read()
{ int x=;bool f=;
char ch=getchar();
while(ch<''||ch>''){f=(ch==);ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+(ch^);ch=getchar();}
return f?(~x+):x;
}
struct edge
{ int next,to;}e[man<<];
inline void add(int from,int to)
{ e[++num].next=head[from];
e[num].to=to;
head[from]=num;
}
int f[man][],dep[man],logn;
bool vis[man];
void bfs(int s,int dept)
{ memset(vis,,sizeof(vis));
f[s][]=-;dep[s]=dept;
queue<int>q;
q.push(s);
do
{ int u=q.front();q.pop();vis[u]=;
for(int i=head[u];i;i=e[i].next)
{ int to=e[i].to;
if(!vis[to])
{ f[to][]=u;
dep[to]=dep[u]+;
q.push(to);}
}
}while(q.size());
}
inline int LCA(int x,int y)
{ if(dep[x]>dep[y]) swap(x,y);
for(int i=;i<logn;i++)
{ if(((dep[y]-dep[x])>>i)&)
y=f[y][i];
}
if(x==y) return x;
for(int i=logn;i>=;i--)
{ if(f[x][i]!=f[y][i])
{ x=f[x][i];
y=f[y][i];
}
}
return f[x][];
}
int main()
{ n=read(),m=read(),root=read();
for(int i=;i<n;i++)
{ int x,y;
x=read(),y=read();
add(x,y);add(y,x);
}
bfs(root,);
logn=(int)(log(n)/log(2.0))+;
for(int j=;j<logn;j++)
for(int i=;i<=n;i++)
if(f[i][j]<) f[i][j+]=-;
else f[i][j+]=f[f[i][j]][j];
for(int i=;i<=m;i++)
{ int x,y;
x=read(),y=read();
printf("%d\n",LCA(x,y));
}
return ;
}

 

[模板]LCA的更多相关文章

  1. 算法模板——LCA(最近公共祖先)

    实现的功能如下——在一个N个点的无环图中,共有N-1条边,M个访问中每次询问两个点的距离 原理——既然N个点,N-1条边,则说明这是一棵树,而且联通.所以以1为根节点DFS建树,然后通过求两点的LCA ...

  2. [模板]LCA的倍增求法解析

    题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...

  3. 模板 树上求LCA 倍增和树链剖分

    //233 模板 LCA void dfs(int x,int f){ for(int i=0;i<E[x].size();i++){ int v = E[x][i]; if(v==f)cont ...

  4. POJ 1330 Nearest Common Ancestors (最近公共祖先LCA + 详解博客)

    LCA问题的tarjan解法模板 LCA问题 详细 1.二叉搜索树上找两个节点LCA public int query(Node t, Node u, Node v) { int left = u.v ...

  5. HDU 2586(LCA欧拉序和st表)

    什么是欧拉序,可以去这个大佬的博客(https://www.cnblogs.com/stxy-ferryman/p/7741970.html)巨详细 因为欧拉序中的两点之间,就是两点遍历的过程,所以只 ...

  6. 浅谈倍增法求解LCA

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

  7. NOIP2015游记——一次开心又失望的旅行

    啊,一年一度的NOIP终于是结束了 以前的大神都有写自己的感受 然而我居然给忘了!!!! 吓得我赶紧来写一份游记 Day.-INF--出发前一个星期 机智的我选择了停课 就是为了OIER这伟大而又光荣 ...

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

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

  9. LCA倍增算法的错误与模板

    先上我原来的错误的代码 type node=^link; link=record num:int64; next:node; end; var fa:..,..] of int64; dep:..] ...

随机推荐

  1. Spring Cloud(Dalston.SR5)--Zuul 网关-微服务集群

    通过 url 映射的方式来实现 zuul 的转发有局限性,比如每增加一个服务就需要配置一条内容,另外后端的服务如果是动态来提供,就不能采用这种方案来配置了.实际上在实现微服务架构时,服务名与服务实例地 ...

  2. sqlserver乱码问题解决

    * 如果是自己创建的数据库那么就应该在一开始就选择排序规则中的:Chinese_PRC_CI_AS 1.改变排序规则方法: 右击创建的数据库,属性→选项→排序规则中选择:Chinese_PRC_CI_ ...

  3. 前段开发神奇webstorm安装注册和汉化

    软件下载地址: http://www.jetbrains.com/webstorm/ 安装完后退出. 重新打开,进行激活 这里我们选择“license server”然后输入:http://idea. ...

  4. 深度图从ros数据类型转换成opencv数据类型

    摘要:ros下,利用realsense D435采集深度图,并将其转换成opencv的数据类型. 一. RGBD图像采集 通过image_transport包,根据给定的采集速度从realsense ...

  5. 【剑指offer】判断出栈序列是否合法

    输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应 ...

  6. Win7系统安装Centos7.0双系统(三)

    4.6语言选择 4.7安装信息设置,除以下几项改动其他都可默认. 软件选择(默认最小):带GUI的服务器或GNOME桌面,可根据使用需要选择安装软件. 磁盘分区:Linux默认可分为3个分区,分别是b ...

  7. 采用ddt 可以把ddt获取的数据 塞进测试用例里面的备注里面去展示 (还没有试)

  8. NodeJS对象数组Array 根据对象object key的值排序sort

    有个js对象数组 var ary=[{id:1,name:”b”},{id:2,name:”b”}] 需求是根据name 或者 id的值来排序,这里有个风骚的函数. /** * 对数组中的对象,按对象 ...

  9. cookie的中文乱码问题【URL编码解码】

    先搞明白为什么会乱码,为什么要转码: 在tomcat 8 之前,cookie中不能直接存储中文数据.需要将中文数据转码,一般采用URL编码(%E3).在tomcat 8 之后,cookie支持中文数据 ...

  10. @SuppressLint("HandlerLeak"),或Handler使用有警告;

    随手写个Handler,然后飘黄,看着挺难受(黄色警告的大概意思:Handler可能会内存泄漏,推荐你用静态内部类+实例化弱引用): This Handler class should be stat ...