st表

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int go[];
int nxt[];
int adj[];
int pos[];
int st[][];
int dep[];
int aa[];
int lg[];
int ecnt,cnt,m,n,s,x,y,a,b;
void add(int u,int v) { //建链前
go[++ecnt]=v;
nxt[ecnt]=adj[u];
adj[u]=ecnt;
}
void dfs(int u,int pre) {
dep[u]=dep[pre]+; //首先预处理出深度
aa[++cnt]=u; //DFS序
pos[u]=cnt; //第几个出现的
for(int e=adj[u]; e; e=nxt[e]) {
if(go[e]!=pre) {
dfs(go[e],u);
aa[++cnt]=u;
}
}
}
int MIN(int p,int q) {
if(dep[p]<dep[q]) return p;
else return q;
}
void build() {
for(int i=; i<=cnt; i++) {
st[i][]=aa[i];
}
for(int i = , j = ; i <= cnt; i++){
if( << (j + ) == i) j++;
lg[i] = j;
}
for(int j=; j<=lg[cnt]; j++) {
for(int i=; i + ( << j) - <=cnt; i++) {
st[i][j]=MIN(st[i][j-],st[i+( << (j - ))][j-]);
}
}
}
/*
读入两个节点,查询它们第一次出现的位置
在这两个位置之间的区间查询最小深度的节点,该节点即为最近公共祖先
*/
int lca(int l,int r) {
int xx=pos[l];
int yy=pos[r];
if(xx>yy) swap(xx,yy);
int k=lg[yy-xx+];
return MIN(st[xx][k],st[yy-( << k)+][k]);
}
template <class T> //快速读入
void read(T &x){
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T> //快速输出
void write(T x){
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
int main() {
//scanf("%d%d%d",&n,&m,&s);
read(n), read(m), read(s);
for(int i=; i<=n-; i++) {
//scanf("%d%d",&x,&y);
read(x), read(y);
add(x,y);
add(y,x);
}
dfs(s,);
build();
for(int i=; i<=m; i++) {
//scanf("%d%d",&a,&b);
//printf("%d\n",lca(a,b));
read(a), read(b);
write(lca(a, b)), putchar('\n');
}
return ;
}

树上倍增和st表的思路一样,只是实现方法不同

/*
倍增求LCA:
father【i】【j】表示节点i往上跳2^j次后的节点
可以转移为
father【i】【j】=father【father【i】【j-1】】【j-1】
(此处注意循环时先循环j,再循环i)
然后dfs求出各个点的深度depth
整体思路:
先比较两个点的深度,如果深度不同,先让深的点往上跳,浅的先不动,
等两个点深度一样时,if 相同 直接返回,if 不同 进行下一步;如果不同
,两个点一起跳,j从大到小枚举(其实并不大),如果两个点都跳这么多后
,得到的点相等,两个点都不动(因为有可能正好是LCA也有可能在LCA上方)
,知道得到的点不同,就可以跳上来,然后不断跳,两个点都在LCA下面那层,
所以再跳1步即可,当father【i】【j】中j=0时即可,就是LCA,返回值结束
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
vector <int> g[];
int father[][]={};
int depth[]={};
int n,m;
bool visit[]={false};
int root;
void dfs(int u)//深搜出各点的深度,存在depth中
{
int i;
visit[u]=true;
for (i=;i<g[u].size();i++)
{
int v=g[u][i];
if ( !visit[v] )
{
depth[v]=depth[u]+;
dfs(v);
}
}
}
void bz()//fa数组的预处理
{
int i,j;
for (j=;j<=;j++)
for (i=;i<=n;i++)
father[i][j]=father[father[i][j-]][j-];
}//倍增,处理father数组,详情参照上述讲解
int LCA(int u,int v)
{
if ( depth[u]<depth[v] )
{
int temp=u;
u=v;
v=temp;
}//保证深度大的点为u,方便操作
int dc=depth[u]-depth[v];
int i;
for (i=;i<;i++)//值得注意的是,这里需要从零枚举
{
if ( (<<i) & dc)//从大到小二分
u=father[u][i];//意思是跳2^j步不一样,就跳,否则不跳
}
//上述操作先处理较深的结点,使两点深度一致
if (u==v) return u;//如果深度一样时,两个点相同,直接返回
for (i=;i>=;i--)//从大到小二分。
{
if (father[u][i]!=father[v][i])//跳2^j步不一样,就跳,否则不跳
{
u=father[u][i];
v=father[v][i];
}
}
u=father[u][];//上述过程做完,两点都在LCA下一层,所以走一步即可
return u;
}
int main()
{
int i,j;
scanf("%d",&n);
for (i=;i<=n;i++)
g[i].clear();
for (i=;i<n;i++)
{
int a,b;
int root;
scanf("%d%d",&a,&b);
g[a].push_back(b);
father[b][]=a;//a^0为1,所以fa[a][0]代表a向上走一格
if (father[a][]==)//如果节点的根为0,证明该节点为根节点
root = a;
}
depth[root]=;
dfs(root);
bz();
int x,y;
scanf("%d%d",&x,&y);
printf("%d",LCA(x,y));
return ;
}

最新文章

  1. RabbitMQ官方中文入门教程(PHP版) 第四部分:路由(Routing)
  2. Ubuntu基础命令
  3. UVa 1593代码对齐
  4. Maven之 学习资料
  5. 使用VS2015(c#)进行单元测试,显示测试结果与查看代码覆盖率
  6. 六,WPF的Application类
  7. JS生成不重复随机数
  8. Haskell Seq函数和严格计算
  9. hdu_5831_Rikka with Parenthesis II(模拟)
  10. HTTP状态码 - HTTP Status Code
  11. Angular+ionic2 web端 启动程序出现短暂 白屏或黑屏 的处理小妙招
  12. xadmin与admin设置
  13. linux-2.6.18源码分析笔记---信号
  14. ElasticSearch-6.2安装head插件
  15. 检测浏览器是否支持ES6
  16. hadoop1.2开发环境搭建
  17. 源码编译vim
  18. 静态代码扫描之阿里java代码规范IDEA插件
  19. CRM 2016 Get IOrganizationService
  20. 记账本,C,Github,entity

热门文章

  1. Mybatis学习总结一
  2. HDU多校Round 8
  3. BZOJ1509: [NOI2003]逃学的小孩 (树形DP)
  4. [Luogu] P4254 [JSOI2008]Blue Mary开公司
  5. springcloud(十):熔断监控Hystrix Dashboard
  6. Cow Sorting POJ 3270 &amp; HDU 2838
  7. nyoj 31 5个数求最值
  8. 《Spring in action》之Spring之旅
  9. HTTP自学心得
  10. HDFS2.0之简单总结