LCA近期公共祖先
LCA近期公共祖先
该分析转之:http://kmplayer.iteye.com/blog/604518
1,并查集+dfs
对整个树进行深度优先遍历。并在遍历的过程中不断地把一些眼下可能查询到的而且结果同样的节点用并查集合并.
2,分类。使每一个结点都落到某个类中,到时候仅仅要运行集合查询,就能够知道结点的LCA了。
对于一个结点u.类别有:
以u为根的子树、除类一以外的以f(u)为根的子树、除前两类以外的以f(f(u))为根的子树、除前三类以外的以f(f(f(u)))为根的子树……
类一的LCA为u,类二为f(u),类三为f(f(u)),类四为f(f(f(u)))。这种分类看起来好像并不困难。
但关键是查询是二维的。并没有一个确定的u。接下来就是这个算法的巧妙之处了。
利用递归的LCA过程。
当lca(u)运行完成后,以u为根的子树已经所有并为了一个集合。而一个lca的内部实际上做了的事就是对其子结点。依此调用lca.
当v1(第一个子结点)被lca。正在处理v2的时候,以v1为根的子树+u同在一个集合里。f(u)+编号比u小的u的兄弟的子树 同在一个集合里,f(f(u)) + 编号比f(u)小的 f(u)的兄弟 的子树 同在一个集合里……
而这些集合,对于v2的LCA都是不同的。
因此仅仅要查询x在哪一个集合里,就能知道LCA(v2,x)
另一种可能。x不在不论什么集合里。当他是v2的儿子,v3,v4等子树或编号比u大的u的兄弟的子树(等等)时。就会发生这样的情况。即还没有被处理。
还没有处理过的怎么办?把一个查询(x1,x2)往查询列表里加入两次,一次加入到x1的列表里,一次加入到x2的列表里,假设在做x1的时候发现 x2已经被处理了。那就接受这个询问。(两次中必然仅仅有一次询问被接受).
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std; const int MAXN = 100000 + 10;
int degree[MAXN];
bool vst[MAXN];
int ancestor[MAXN];
int f[MAXN];
int rank[MAXN];
vector<int> tree[MAXN];
vector<int> Qes[MAXN]; int N;
void init(){
for(int i = 0;i <= N;++i){
degree[i] = 0;
vst[i] = false;
ancestor[i] = -1;
f[i] = i;
rank[i] = 0;
tree[i].clear();
Qes[i].clear();
}
} int find(int x){
if(x == f[x])
return x;
return f[x] = find(f[x]);
} void setUnion(int u,int v){
int a = find(u),b = find(v);
if(a != b){
if(rank[a] < rank[b]){
f[a] = b;
} else {
f[b] = a;
if(rank[a] == rank[b]) rank[a]++;
}
}
} void LCA(int u){
ancestor[u] = u;
int sz = tree[u].size();
for(int i = 0;i < sz;++i){
LCA(tree[u][i]);
setUnion(u,tree[u][i]);
ancestor[find(u)] = u;
} vst[u] = 1;
sz = Qes[u].size();
for(int i = 0;i < sz;++i){
if(vst[Qes[u][i]]){
printf("%d\n",ancestor[find(Qes[u][i])]);
return;
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
int x,y;
scanf("%d",&N);
init();
for(int i = 1;i < N;++i){
scanf("%d%d",&x,&y);
degree[y]++;
tree[x].push_back(y);
} int s,t;
scanf("%d%d",&s,&t);
Qes[s].push_back(t);
Qes[t].push_back(s); for(int i = 1;i <= N;++i){
if(degree[i] == 0){
LCA(i);
break;
}
}
}
return 0;
}
LCA近期公共祖先的更多相关文章
- LCA 近期公共祖先 小结
LCA 近期公共祖先 小结 以poj 1330为例.对LCA的3种经常使用的算法进行介绍,分别为 1. 离线tarjan 2. 基于倍增法的LCA 3. 基于RMQ的LCA 1. 离线tarjan / ...
- 连通分量模板:tarjan: 求割点 && 桥 && 缩点 && 强连通分量 && 双连通分量 && LCA(近期公共祖先)
PS:摘自一不知名的来自大神. 1.割点:若删掉某点后.原连通图分裂为多个子图.则称该点为割点. 2.割点集合:在一个无向连通图中,假设有一个顶点集合,删除这个顶点集合,以及这个集合中全部顶点相关联的 ...
- POJ 1470 Closest Common Ancestors【近期公共祖先LCA】
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u013912596/article/details/35311489 题目链接:http://poj ...
- 近期公共祖先(LCA)——离线Tarjan算法+并查集优化
一. 离线Tarjan算法 LCA问题(lowest common ancestors):在一个有根树T中.两个节点和 e&sig=3136f1d5fcf75709d9ac882bd8cfe0 ...
- HDU 2586 How far away ?(LCA模板 近期公共祖先啊)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the vi ...
- POJ1330Nearest Common Ancestors——近期公共祖先(离线Tarjan)
http://poj.org/problem? id=1330 给一个有根树,一个查询节点(u,v)的近期公共祖先 836K 16MS #include<iostream> #includ ...
- LintCode 近期公共祖先
中等 近期公共祖先 查看执行结果 34% 通过 给定一棵二叉树,找到两个节点的近期公共父节点(LCA). 近期公共祖先是两个节点的公共的祖先节点且具有最大深度. 您在真实的面试中是否遇到过这个题? Y ...
- 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 ...
随机推荐
- spring cloud-给Eureka Server加上安全的用户认证
前言 在前面的一篇文章中 spring cloud中启动Eureka Server 我们启动了Eureka Server,然后在浏览器中输入http://localhost:8761/后,直接回车,就 ...
- 20 个具有惊艳效果的 jQuery 图像缩放插件
jQuery相对与Flash的魔力已经贯穿整个网络.尽管,Flash层被认为是用于网页设计的首选,然而随着jQuery的出现,以及他的酷似Flash的交互式特效使得网页更加的优雅——Flash开始靠边 ...
- java 切图 判断图片是否是纯色/彩色图片
首先上切图的代码 /** * 图片剪裁 * @param x 距离左上角的x轴距离 * @param y 距离左上角的y轴距离 * @param width 宽度 * @param height 高度 ...
- matlab中help所有函数功能的英文翻译
doc funname 在帮助浏览器中打开帮助文档 help funname 在命令窗口打开帮助文档 helpbrowser 直接打开帮助浏览器 lookfor funname 搜索某个关键字相关函数 ...
- OSX:不同OSX版本号的标记可能不兼容-续
不同OSX版本号的标记可能不兼容-续: 经过測试,10.10DP2的Update.俗称DP3.的版本号也没有纠正这个问题.而造成该问题的是安装过程中一開始就选择中文,假设安装时使用英文.在第一次进入操 ...
- Delegate模式
转载:http://www.cnblogs.com/limlee/archive/2012/06/13/2547367.html 代理模式 顾名思义就是委托别人去做事情. IOS中经常会遇到的两种情况 ...
- Discuz常见小问题-网站如何备份和恢复
进入后台之后,点击UCenter,然后在左侧的数据备份中点击提交,大概一两分钟会显示备份完成 备份好的数据在uc_server的data/backup文件夹中(文件名为时间+随机字符,里面就一个数据库 ...
- Python网络编程 - 请求地址上的文件并下载
我们用到了requests库,由于是第三方的,必须下载 如果是python 2.x用下面命令 pip install requests python 3.x用下面命令 easy_install req ...
- Android 之布局(一)
Android的布局类型: 主要有:LinearLayout(线性布局).RelativeLayout(相对布局).TableLayout(表格布局).AbsoluteLayout(绝对布局).Fra ...
- Maven的settings.xml文件结构之mirrors
Maven的远程库提供大量构件,供Maven项目直接下载使用.对于一个Maven项目,如果没有特别声明,默认使用Maven的central库,url如下: http://repo.maven.apac ...