题目链接:http://poj.org/problem?id=1330

题意:给定一个n个节点的有根树,以及树中的两个节点u,v,求u,v的最近公共祖先。

数据范围:n [2, 10000]

思路:从树根出发进行后序深度优先遍历,设置vis数组实时记录是否已被访问。

每遍历完一棵子树r,把它并入以r的父节点p为代表元的集合。这时判断p是不是所要求的u, v节点之一,如果r==u,且v已访问过,则lca(u, v)必为v所属集合的代表元。p==v的情况类似。

我的第一道LCA问题的Tarjan算法,题目只有唯一的一组查询,实现起来非常简洁。

注意题目给树的格式:给出n-1个数对<u, v>,u为v的父节点。因此可以当作有向图用邻接表存储,同时记录各个节点的入度,入度为0的点为树根。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 using namespace std;
 5 const int MAX_N = 10005;
 6 int parent[MAX_N];
 7 void init(){
 8     for(int i=0; i<MAX_N; i++){
 9         parent[i] = i;
10     }
11 }
12 int find(int x){
13     if(parent[x] == x) return x;
14     return parent[x] = find(parent[x]);
15 }
16 void unite(int x, int y){
17     x = find(x);
18     y = find(y);
19     if(x == y) return ;
20     parent[y] = x;
21 }
22 bool same(int x, int y){
23     return find(x) == find(y);
24 }
25 vector<int> G[MAX_N];
26 int u, v;
27 int T;
28 int n;
29 int vis[MAX_N];
30 int indeg[MAX_N];
31 void dfs(int r){
32     //printf("%d\n", r);
33     for(int i=0; i<G[r].size(); i++){
34         if(!vis[G[r][i]]){
35             dfs(G[r][i]);
36             unite(r, G[r][i]);//孩子合并到父节点
37         }
38     }
39     vis[r] = 1; //后序遍历
40     if(r == u && vis[v]){
41         printf("%d\n", find(v));
42         return ;
43     }else if(r == v && vis[u]){
44         printf("%d\n", find(u));
45         return ;
46     }
47 }
48 void lca(){
49     memset(vis, 0, sizeof(vis));
50     init();
51     int r = 0;
52     for(int i=1; i<=n; i++){
53         if(indeg[i]==0){
54             //printf("root : %d\n", i); //入度为0的是树根
55             dfs(i);
56         }
57     }
58 }
59 int main()
60 {
61     scanf("%d", &T);
62     while(T--){
63         scanf("%d", &n);
64         memset(indeg, 0, sizeof(indeg));
65         for(int i=0; i<MAX_N; i++) G[i].clear();
66         for(int i=0; i<n-1; i++){
67             scanf("%d%d", &u, &v);
68             G[u].push_back(v);//有向图
69             indeg[v]++;
70         }
71         scanf("%d%d", &u, &v);
72         lca();
73     }
74     return 0;
75 }

转载于:https://www.cnblogs.com/shixinzei/p/7286580.html

POJ 1330 Nearest Common Ancestors(LCA Tarjan算法)相关推荐

  1. poj 1330 Nearest Common Ancestors LCA/DFS

    题目链接: http://poj.org/problem?id=1330 题意: 求出两点间的最近公共祖先. 题解: 第一种: 并查集维护:http://www.cnblogs.com/procedu ...

  2. POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)...

    POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...

  3. POJ 1330 Nearest Common Ancestors 【LCA模板题】

    任意门:http://poj.org/problem?id=1330 Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000 ...

  4. POJ - 1330 Nearest Common Ancestors(树上倍增/树链剖分求LCA)

    题目链接:点击查看 题目大意:给出一棵有根树,我们需要求出两个点的lca 题目分析:因为题目说了是有根树,所以我们在建图的时候直接建有向图就好了,并且记录一下每个点的入度,建完图后找一下入度为0的点, ...

  5. POJ 1330:Nearest Common Ancestors【lca】

    题目大意:唔 就是给你一棵树 和两个点,问你这两个点的LCA是什么 思路:LCA的模板题,要注意的是在并查集合并的时候并不是随意的,而是把叶子节点合到父节点上 #include<cstdio&g ...

  6. [POJ 1330] Nearest Common Ancestors (倍增法)

    题目同上篇,最近公共祖先. 因为没有清零tot,RE了好多次TAT 一定要初始化啊!! 1 #include<cstdio> 2 #include<cstring> 3 #in ...

  7. POJ - 1330 Nearest Common Ancestors tanjan_LCA

    传送门 题意就是题目 所谓在线,就是一个一个贼笨且时间太长. #include<stdio.h> #include<string.h> #include<iostream ...

  8. Nearest Common Ancestors(LCA板子)

    题目链接:http://poj.org/problem?id=1330 Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 1000 ...

  9. LCA——JD 3055 Nearest Common Ancestors

    3055: Nearest Common Ancestors Time Limit: 1 Sec   Memory Limit: 128 MB Description 给定N个节点的一棵树,有K次查询 ...

  10. JDOJ 3055: Nearest Common Ancestors

    JDOJ 3055: Nearest Common Ancestors JDOJ传送门 Description 给定N个节点的一棵树,有K次查询,每次查询a和b的最近公共祖先. 样例中的16和7的公共 ...

最新文章

  1. 程序员的月薪 | 每日趣闻
  2. 实用工具类库java.util
  3. pgsql的存储过程调用mysql_PostgreSQL存储过程循环调用方式
  4. Tween 若干年后我尽然还要学数学 曲线到底是什么鬼啊
  5. ORACLE基础应用学习-- 各种故障的恢复方法总结
  6. api 获取网络使用情况_您的API是什么情况?
  7. 计算机课程中lnA怎么打,《计算机基础》考试模拟题(含答案)
  8. myisam读取速度为什么比innodb快_为什么MySQL用B+树做索引
  9. 数据结构(四)之冒泡排序
  10. wget下载网络图片
  11. Extjs4.1.1视频教程下载
  12. 由系统函数求零极点图、频率响应(幅频特性、相频特性)的 Matlab 和 Python 方法
  13. 【转】无线路由器密码破解
  14. java 微信 图灵机器人_使用图灵api创建微信聊天机器人
  15. 笔记本或台式机进入BIOS的快捷键
  16. 程序员眼中的中国传统文化-王阳明《传习录》16
  17. 期货与期权套期保值的对比研究
  18. 我们为什么做Banana Pi开源硬件项目:
  19. unity中3D数学相关类、属性、方法、用途总结+超级综合的案例
  20. python 路径格式化_吐血整理!140种Python标准库、第三方库和外部工具都有了!...

热门文章

  1. 学历真的改变能命运? | 数据告诉你
  2. 计算机科学为什么重要,数学 – 为什么在计算机科学中有8和256个如此重要的数字?...
  3. Noise,Error,wighted pocket Algorithm
  4. 浏览器加载渲染网页过程解析
  5. Swift基础语法: 21 - Swift的可变形形参, 常量形参, 变量形参, In-Out形参
  6. Python代码规范
  7. 关于 C# 请求 https 那点事
  8. Scrum 的每日例会 和 故事墙
  9. MySQL 四种事务隔离级的说明
  10. Facebook 游戏开发更新文档 API 参考文档 v5.0