POJ 1330 LCA裸题~
Description
In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree. Node x is an ancestor of node y if node x is in the path between the root and node y. For example, node 4 is an ancestor of node 16. Node 10 is also an ancestor of node 16. As a matter of fact, nodes 8, 4, 10, and 16 are the ancestors of node 16. Remember that a node is an ancestor of itself. Nodes 8, 4, 6, and 7 are the ancestors of node 7. A node x is called a common ancestor of two different nodes y and z if node x is an ancestor of node y and an ancestor of node z. Thus, nodes 8 and 4 are the common ancestors of nodes 16 and 7. A node x is called the nearest common ancestor of nodes y and z if x is a common ancestor of y and z and nearest to y and z among their common ancestors. Hence, the nearest common ancestor of nodes 16 and 7 is node 4. Node 4 is nearer to nodes 16 and 7 than node 8 is.
For other examples, the nearest common ancestor of nodes 2 and 3 is node 10, the nearest common ancestor of nodes 6 and 13 is node 8, and the nearest common ancestor of nodes 4 and 12 is node 4. In the last example, if y is an ancestor of z, then the nearest common ancestor of y and z is y.
Write a program that finds the nearest common ancestor of two distinct nodes in a tree.
Input
Output
Sample Input
- 2
- 16
- 1 14
- 8 5
- 10 16
- 5 9
- 4 6
- 8 4
- 4 10
- 1 13
- 6 15
- 10 11
- 6 7
- 10 2
- 16 3
- 8 1
- 16 12
- 16 7
- 5
- 2 3
- 3 4
- 3 1
- 1 5
- 3 5
Sample Output
- 4
- 3
最近在复习一些暑假集训时候学到的一些数据结构,这次的主题是LCA(最近公共祖先),找出一棵树里边任意两个节点的最近公共祖先节点(这个称呼不太科学?),这是一道全裸的LCA的题目,有两种解决思路
方法一:对于每次查询的两个节点,先让两个节点上升到同一个深度的地方,然后两个节点在同时上升,直到两个节点相遇为止,相遇的点即为最近公共祖先。
方法二:先让某个节点一直往上走一直走到根节点,并开一个数组记录这个路径,让后再让另一个节点往上走,直到与前一个节点产生的路径相交为止,那么这个交点也是两个节点的最近公共祖先啦~- 方法1的AC代码:
- /*********************************
- Author: jusonalien
- Email : jusonalien@qq.com
- school: South China Normal University
- Origin:
- *********************************/
- #include <cstdio>
- #include <vector>
- #include <cstring>
- using namespace std;
- const int maxn = ;
- vector<int>G[maxn];
- int depth[maxn],father[maxn];
- int root,n;
- void dfs(int v,int p,int d){//通过dfs构造出一棵树,并且记录每个节点的深度,这个很重要!
- depth[v] = d;
- for(int i = ;i < G[v].size();++i){
- if(G[v][i] != p) dfs(G[v][i],v,d+);
- }
- return ;
- }
- int lca(int u,int v){
- while(depth[u] > depth[v]) u = father[u];
- while(depth[v] > depth[u]) v = father[v];
- while(u != v){
- u = father[u];
- v = father[v];
- }
- return u;
- }
- void init(){
- memset(depth,,sizeof(depth));
- memset(father,-,sizeof(father));
- for(int i = ;i <= n;++i) G[i].clear();
- }
- void print(){//调试代码
- for(int i = ;i <= n;++i) printf("%02d ",father[i]);
- puts("");
- for(int i = ;i <= n;++i) printf("%02d ",depth[i]);
- puts("");
- }
- int main(){
- int cas;
- int a,b;
- scanf("%d",&cas);
- while(cas--){
- scanf("%d",&n);
- init();
- for(int i = ;i < n;++i){
- scanf("%d%d",&a,&b);
- father[b] = a;
- G[a].push_back(b);
- }
- for(int i = ;i <= n;++i)
- if(father[i] == -){
- root = i;break;
- }
- dfs(root,-,);
- //print();
- scanf("%d%d",&a,&b);
- printf("%d\n",lca(a,b));
- }
- return ;
- }
方法2的AC代码:
- #include <cstdio>
- #include <cstring>
- using namespace std;
- int const maxn = +;
- int fa[maxn];
- bool vis[maxn];
- int n;
- int main()
- {
- int T;
- scanf("%d",&T);
- while(T--)
- {
- int u,v;
- scanf("%d",&n);
- memset(vis,,sizeof(vis));
- memset(fa,,sizeof(fa));
- for(int i=;i<n;++i)
- {
- scanf("%d%d",&u,&v);
- fa[v]=u;
- }
- scanf("%d%d",&u,&v);
- do
- {
- vis[u]=true;
- u=fa[u];
- }while(u!=);
- do
- {
- if(vis[v])
- {
- printf("%d\n",v);
- break;
- }
- v=fa[v];
- }while(v!=);
- }
- return ;
- }
个人觉得,方法1对于同一棵树上的大规模查询的效率要比方法2要高,并且当查询的节点大都在树的底层的时候,方法2会产生很多不必要的查询,也会产生较多的浪费(并且个人觉得方法1的代码更加优美?
Ps:这里有一份很不错的关于RMQ和LCA的学习资料介绍,请猛戳此处 选自农夫三拳。
POJ 1330 LCA裸题~的更多相关文章
- JZOJ5883【NOIP2018模拟A组9.25】到不了——动态LCA裸题
题目描述 Description wy 和 wjk 是好朋友. 今天他们在一起聊天,突然聊到了以前一起唱过的<到不了>. "说到到不了,我给你讲一个故事吧." &quo ...
- poj 1330 LCA
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #i ...
- poj 1330 LCA (倍增+离线Tarjan)
/* 先来个倍增 */ #include<iostream> #include<cstring> #include<cstdio> #define maxn 100 ...
- POJ 3264 RMQ裸题
POJ 3264 题意:n个数,问a[i]与a[j]间最大值与最小值之差. 总结:看了博客,记下了模板,但有些地方还是不太理解. #include<iostream> #include&l ...
- poj 1330 LCA最近公共祖先
今天学LCA,先照一个模板学习代码,给一个离线算法,主要方法是并查集加上递归思想. 再搞,第一个离线算法是比较常用了,基本离线都用这种方法了,复杂度O(n+q).通过递归思想和并查集来寻找最近公共祖先 ...
- POJ 1330 LCA最近公共祖先 离线tarjan算法
题意要求一棵树上,两个点的最近公共祖先 即LCA 现学了一下LCA-Tarjan算法,还挺好理解的,这是个离线的算法,先把询问存贮起来,在一遍dfs过程中,找到了对应的询问点,即可输出 原理用了并查集 ...
- POJ.1330 Nearest Common Ancestors (LCA 倍增)
POJ.1330 Nearest Common Ancestors (LCA 倍增) 题意分析 给出一棵树,树上有n个点(n-1)条边,n-1个父子的边的关系a-b.接下来给出xy,求出xy的lca节 ...
- POJ 1330 Nearest Common Ancestors 倍增算法的LCA
POJ 1330 Nearest Common Ancestors 题意:最近公共祖先的裸题 思路:LCA和ST我们已经很熟悉了,但是这里的f[i][j]却有相似却又不同的含义.f[i][j]表示i节 ...
- POJ - 1330 Nearest Common Ancestors(dfs+ST在线算法|LCA倍增法)
1.输入树中的节点数N,输入树中的N-1条边.最后输入2个点,输出它们的最近公共祖先. 2.裸的最近公共祖先. 3. dfs+ST在线算法: /* LCA(POJ 1330) 在线算法 DFS+ST ...
随机推荐
- [LUOGU] P1316 丢瓶盖
题目描述 陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢? 输入输出 ...
- 并不简单的Integer
Integer是一个看着挺简单的,其实还是有点不一样,Integer是一个int的包装类,它是可以起到缓存作用的,在java基础里说过它的范围是(-128-127)在这个返回是有缓存的,不会创建新的I ...
- PHP:分页类(比较庞大不建议在项目中用)
文章来源:http://www.cnblogs.com/hello-tl/p/7685178.html <?php //地址 //page::$url=''; //每页的条数 默认10 //pa ...
- Final Battle #1 K题 Fire game
Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows ...
- Vue如何在data中正常引入图片路径
在Vue项目中通过data设置图片路径,然后在template中引入后页面无法显示图片,浏览器控制台报错: 刚开始以为是路径出问题了,于是绝对路径.相对路 ...
- 详解js变量声明提升
之前一直觉会认为javascript代码执行是由上到下一行行执行的.自从看了<你不知道的JS>后发现这个观点并不完全正确.先来给大家举一个书本上的的例子: var a='hello wor ...
- 【转】Java读写文件大全
使用Java操作文本文件的方法详解 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类,这两个类都是抽象类,Writer中 write(ch ...
- 【Intellij 】Intellij IDEA 添加jar包的三种方式
一.直接复制:(不推荐) 方法:直接将硬盘上的jar包复制粘贴到项目的lib目录下即可. 注意: 1.对于导入的eclipse项目,该方式添加的jar包没有任何反应,用make编译项目会报错 2.对于 ...
- spring面试相关点
刚刚开通博客,因为最近在进行各种面试,遇到各种面试问题,用这个机会整理几篇文章方便日后需要 springmvc 和springboot spring boot只是一个配置工具,整合工具,辅助工具. s ...
- Serv-u 10.3 的图文安装教程及使用方法
现在很多windows服务器都是使用serv_u作为ftp服务器,一般情况下我们使用Serv-U FTP Server v6.4.0.6,这里以serv_u 10.3为例介绍下,方便需要的朋友 一 ...