/*
* LCA在线算法(倍增法)
*/
const int MAXN = 10010;
const int DEG = 20; struct Edge
{
int to, next;
} edge[MAXN * 2]; int head[MAXN], tot;
void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
} void init()
{
tot = 0;
memset(head, -1, sizeof(head));
} int fa[MAXN][DEG]; // fa[i][j]表示结点i的第2^j个祖先
int deg[MAXN]; // 深度数组 void BFS(int root)
{
queue<int>que;
deg[root] = 0;
fa[root][0] = root;
que.push(root);
while (!que.empty())
{
int tmp = que.front();
que.pop();
for (int i = 1; i < DEG; i++)
{
fa[tmp][i] = fa[fa[tmp][i - 1]][i - 1];
}
for (int i = head[tmp]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if (v == fa[tmp][0])
{
continue;
}
deg[v] = deg[tmp] + 1;
fa[v][0] = tmp;
que.push(v);
}
}
} int LCA(int u, int v)
{
if (deg[u] > deg[v])
{
swap(u, v);
}
int hu = deg[u], hv = deg[v];
int tu = u, tv = v;
for (int det = hv-hu, i = 0; det ; det >>= 1, i++)
{
if (det & 1)
{
tv = fa[tv][i];
}
}
if (tu == tv)
{
return tu;
}
for (int i = DEG - 1; i >= 0; i--)
{
if (fa[tu][i] == fa[tv][i])
{
continue;
}
tu = fa[tu][i];
tv = fa[tv][i];
}
return fa[tu][0];
} bool flag[MAXN]; int main()
{
int T;
int n;
int u, v;
scanf("%d", &T); while(T--)
{
scanf("%d", &n);
init();
memset(flag, false, sizeof(flag));
for (int i = 1; i < n; i++)
{
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
flag[v] = true;
}
int root;
for (int i = 1; i <= n; i++)
{
if (!flag[i])
{
root = i;
break;
}
}
BFS(root);
scanf("%d%d", &u, &v);
printf("%d\n", LCA(u, v));
}
return 0;
}

图论--LCA--树上倍增法(在线)的更多相关文章

  1. 最近公共祖先算法LCA笔记(树上倍增法)

    Update: 2019.7.15更新 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了. 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了 ...

  2. 树上倍增法求LCA

    我们找的是任意两个结点的最近公共祖先, 那么我们可以考虑这么两种种情况: 1.两结点的深度相同. 2.两结点深度不同. 第一步都要转化为情况1,这种可处理的情况. 先不考虑其他, 我们思考这么一个问题 ...

  3. Codevs 2370 小机房的树 LCA 树上倍增

    题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子, ...

  4. HDU 4822 Tri-war(LCA树上倍增)(2013 Asia Regional Changchun)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4822 Problem Description Three countries, Red, Yellow ...

  5. LCA树上倍增

    LCA就是最近公共祖先,比如 节点10和11的LCA就是8,9和3的LCA就是3. 我们这里讲一下用树上倍增来求LCA. 大家都可以写出暴力解法,两个节点依次一步一步往上爬,直到爬到了相同的一个节点. ...

  6. 关于树论【LCA树上倍增算法】

    补了一发LCA,表示这东西表面上好像简单,但是细节真挺多. 我学的是树上倍增,倍增思想很有趣~~(爸爸的爸爸叫奶奶.偶不,爷爷)有一个跟st表非常类似的东西,f[i][j]表示j的第2^i的祖先,就是 ...

  7. LCA——树上倍增

    首先,什么是LCA? LCA:最近公共祖先 祖先:从当前点到根节点所经过的点,包括他自己,都是这个点的祖先 A和B的公共祖先:同时是A,B两点的祖先的点 A和B的最近公共祖先:深度最大的A和B的公共祖 ...

  8. lca入门———树上倍增法(博文内含例题)

    倍增求LCA: father[i][j]表示节点i往上跳2^j次后的节点 可以转移为 father[i][j]=father[father[i][j-1]][j-1] 整体思路: 先比较两个点的深度, ...

  9. 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增

    倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...

随机推荐

  1. django、celery异步发邮件

    django.celery异步发邮件 django自带的send_mail发邮件功能执行发邮件功能会因为网络的原因造成花费的时间过长,为了解决这个问题,可以用celery + redis代替 安装包: ...

  2. Linux网络安全篇,FTP服务器的架设

    一.FTP简介 FTP基于TCP协议.而且FTP服务器使用了命令通道和数据流通道两个连接.两个连接都会分别进行三次握手.在命令通道中客户端会随机取一个大于1024的端口与FTP服务器的21端口建立连接 ...

  3. C/C++内存详解

    众所周知,堆和栈是数据结构中的两种数据结构类型,堆是一种具有优先顺序的完全二叉树(或者说是一种优先队列,因为它在一定的优先顺序下满足队列先进先出的特点),排队打饭就是它的典型实例,栈是一种后进先出的数 ...

  4. C语言 文件复制

    有很多人会问,学会C语言能干啥?,就只能控制台敲个数学题,做个界面都没有的贪吃蛇么? 刚开始的我,也是这样想的,但慢慢深入C语言后,我才领略到C的强大,C的万能.小到游戏破解,加解密算法,大到设备驱动 ...

  5. javascript入门 之 ztree(七 结点的查询)

    <!DOCTYPE html> <HTML> <HEAD> <meta http-equiv="content-type" content ...

  6. Struts2-学习笔记系列(8)-异常处理

    后台抛出自定义异常 public String execute() throws Exception { if (getUser().equalsIgnoreCase("user" ...

  7. CocoaPods应用于iOS项目框架管理方案

  8. 【Java】WrapperClass 包装类

    什么是包装类? 写写我的想法 就是对于对象和基本类型的无法匹配和强转,基本类型在面向对象的实例类型中,反而成了个特殊的数据类型的存在 在一些特定的情况,我们希望通过对象的方式去处理数据,但是基本类型的 ...

  9. 简单网络编程如何用python来实现

    对于网络编程,通信模式是后台必备技能,先用最基础代码实现,理解一些 API 的含义,在深入学习. 总是有读者问过我关于 Python 后台开发相关,如果想走 Python 后台方向,对于 Python ...

  10. C - N皇后问题 DFS

    在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上. 你的任务是,对于给定的N,求出有多少种合法的放置方法. Inpu ...