原题目参见:1143 Lowest Common Ancestor (30分)
        思路:查找第一个数的过程中标记所有访问过的节点。在查找第二个数的时候,所有访问过的路径节点,如果被第一个数字访问过,则说明这个节点是两个数字的共同祖先,将答案更新为此节点,直至最深处的一个共同节点,该答案即为所求。
        因为第一个数据访问的路径上标志位已经被修改,所以需要记录第一次路径中的最后一个节点,通过递推访问其父节点,重置路径上的标志位,即可保证在每次查询时候所有的标志位都是干净的。
        另外注意,输入的树由于不满足红黑树的性质,仅仅是普通的查找二叉树,所以很可能存在如1 2 3 4 5 6 … 10,000,退化成一条链式结构,使用自己写的二叉查找树,每次查询可能会从O(logn)(约14)退化为O(n)(最差10000)的查询时间。
        不过经测试,即使采用自己写的二叉查找树,测试点4的时间用时约190ms,不会超过题目要求的200ms。如果采用自己书写的二叉查找树,可以设置一个剪枝条件:在处理输入时,保存树中的最小和最大节点,如果查询值超过了树的表示范围,则可以直接判定不在二叉查找树中。这个剪枝大约可以节省30ms的时间,测试点4用时约160ms。
        否则,可以使用set.count()判断查询点是否在树中,因为set采用红黑树作为载体结构,且题目保证所有节点的关键字值不相等,所以可以保证每次查询节点是否在树中的时候花费O(logn)的时间,但是在判断两个查询数值LCA的时候,仍然需要以原始树结构为标准。使用set结构后,测试点4用时约125ms。

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <set>
using namespace std;const int maxn = 10010;
int pre[maxn];
set<int> tree;
struct Node {public:int d, visted;Node* lchild, * rchild, *father;
};Node* createNode(int data) {Node* root = new Node;root->d = data;root->visted = 0;root->lchild = root->father = root->rchild = NULL;return root;
}Node* createBST(int l, int r) {if (l == r) {return createNode(pre[l]);}int rootd = pre[l];int rtrid = l + 1;Node* root = createNode(rootd);for (; rtrid <= r; rtrid++) {if (pre[rtrid] > rootd) {break;}}if (rtrid != l + 1) {root->lchild = createBST(l + 1, rtrid - 1);root->lchild->father = root;}if (rtrid != r + 1) {root->rchild = createBST(rtrid, r);root->rchild->father = root;}return root;
}int tagFind(int x, Node* root, Node*& last) {if (root == NULL) {return 0;}root->visted = 1;last = root;if (root->d == x) {return 1;}else if (x < root->d) {return tagFind(x, root->lchild, last);}else {return tagFind(x, root->rchild, last);}
}int findLCA(int x, Node* root, int& ans) {if (root == NULL) {return 0;}if (root->visted) {ans = root->d;}if (root->d == x) {return 1;}else if (x < root->d) {return findLCA(x, root->lchild, ans);}else {return findLCA(x, root->rchild, ans);}
}int clearTag(Node* last) {while (last != NULL) {last->visted = 0;last = last->father;}return 0;
}int lca(int a, int b, Node* root) {Node* last = NULL;int ans = 0;int flaga, flagb;if (!tree.count(a)) {flaga = 0;}else {flaga = tagFind(a, root, last);}if (!tree.count(b)) {flagb = 0;}else {flagb = findLCA(b, root, ans);}clearTag(last);if (flaga && flagb) {if (ans == a) {printf("%d is an ancestor of %d.\n", a, b);}else if (ans == b) {printf("%d is an ancestor of %d.\n", b, a);}else {printf("LCA of %d and %d is %d.\n", a, b, ans);}}else if (!flaga && !flagb) {printf("ERROR: %d and %d are not found.\n", a, b);}else if (!flaga && flagb) {printf("ERROR: %d is not found.\n", a);}else if (flaga && !flagb) {printf("ERROR: %d is not found.\n", b);}return 0;
}int main()
{int n, m, a, b;scanf("%d%d", &m, &n);for (int i = 0; i < n; i++) {scanf("%d", &pre[i]);tree.insert(pre[i]);}Node* root = createBST(0, n - 1);for (int i = 0; i < m; i++) {scanf("%d%d", &a, &b);lca(a, b, root);}return 0;
}

1143 Lowest Common Ancestor (30分) 附测试点分析相关推荐

  1. PAT甲级1143 Lowest Common Ancestor (30 分):[C++题解]LCA、最低公共祖先

    文章目录 题目分析 题目链接 题目分析 来源:acwing 分析:二叉搜索树的中序遍历是隐含给定的,它的中序遍历就是从小到大排列. 所以这道题先是根据给定的前序遍历和中序遍历,建树. 建树的时候需要用 ...

  2. 【题解】【PAT甲】1143 Lowest Common Ancestor (30 分)(树)(BST)(最近公共祖先)

    题目链接 PTA | 程序设计类实验辅助教学平台 题目描述 The lowest common ancestor (LCA) of two nodes U and V in a tree is the ...

  3. 1143 Lowest Common Ancestor (30 分)【难度: 中 / 知识点: 最低公共祖先 未完成】

    https://pintia.cn/problem-sets/994805342720868352/problems/994805343727501312

  4. 1143. Lowest Common Ancestor

    1143. Lowest Common Ancestor (30) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yu ...

  5. 团体天梯 L3-022 地铁一日游 (30 分)(测试点分析 and 推荐测试样例)

    L3-022 地铁一日游 (30 分) 森森喜欢坐地铁.这个假期,他终于来到了传说中的地铁之城--魔都,打算好好过一把坐地铁的瘾! 魔都地铁的计价规则是:起步价 2 元,出发站与到达站的最短距离(即计 ...

  6. 1143 Lowest Common Ancestor(建树与不建两种思路)

    目录 解法一 解法二 解法一 这题可以不建树,直接利用BST的性质:左子树<根节点<右子树,对先序序列进行遍历,如果有某个元素大于等于u,v中较小的且小于等于u,v中较大的,则可能是根节点 ...

  7. 1143 Lowest Common Ancestor 甲级

    题意: 给出一棵二叉搜索树的前序遍历,问结点u和v的共同最低祖先是谁,利用先序遍历特点. 二叉搜索树满足: 节点的左子树只包含键小于节点键的节点. 节点的键只包含节点的右键大于或等于子树的节点的键. ...

  8. C语言二叉树的lowest common ancestor最低公共祖先(附完整源码)

    C语言二叉树的lowest common ancestor最低公共祖先 C语言二叉树的lowest common ancestor最低公共祖先完整源码(定义,实现,main函数测试) C语言二叉树的l ...

  9. C++lowest common ancestor最近公共祖先算法(附完整源码)

    C++lowest common ancestor最近公共祖先算法 C++lowest common ancestor最近公共祖先算法完整源码(定义,实现,main函数测试) C++lowest co ...

  10. PAT A1143 Lowest Common Ancestor ——沉舟侧畔千帆过,病树前头万木春

    PAT A1143 Lowest Common Ancestor 第一次遇到LCA,想的比较乱,感觉有点并查集的意思,又好像不行.开始的想法是用BST的性质和前序建树,建树过程中做一个father数组 ...

最新文章

  1. java bean工厂_从零构建轻量级Java Web框架
  2. android gdb 远程调试工具,Android下用gdb远程调试办法
  3. [JavaWeb-MySQL]数据库的备份和还原
  4. java 8的一些新用法
  5. 如何实现Punycode中文域名转码
  6. PHP7 网络编程(四)signal信号【待】
  7. PIX525-IPSEC-×××配置
  8. 关于SVN更新时文件加锁的小结
  9. MySQL:JDBC基础及连接数据库的方式
  10. DOS控制台启动方式+DOS控制台常用命令
  11. 数据库设计之需求分析
  12. 分享几个国外模板网站(网页素材的下载)
  13. 在C语言中使用中文,本地化全攻略
  14. 计算机三级路由器配置例题,计算机三级网络技术(7):路由器配置及使用(上)...
  15. OSChina 周五乱弹 ——国庆第六天,每逢佳节胖三斤
  16. 超详细如何配置将WAN接入
  17. markdown使用数学符号/特殊符号
  18. 如何把密码写入代码,让VBA自动撤销工作表保护 / 工作簿保护(使用VBA代码 保护工作表 / 工作簿 和取消保护工作表 / 工作簿)
  19. 基于javaweb的高校运动会管理系统(java+ssm+jsp+js+jquery+mysql)
  20. OPJ---7830:求小数的某一位

热门文章

  1. 图像超分辨率重建原理学习
  2. 揭秘 | 2021年移动云API大赛决赛大奖花落谁家?
  3. 东方证券万字报告:微信视频号进入稳定的发展期
  4. mac ps安装 服务器无响应,Mac程序无响应?六个方法教你如何退出无响应的程序...
  5. 网站域名假墙处理方法 内含cloudflare API自动更换IP的php脚本
  6. Unity脚本:寻找血量最低的敌人
  7. 计算机网络的概念、功能、组成和分类
  8. 今日睡眠质量记录77分
  9. java之成员变量(实例成员变量和静态成员变量)
  10. 8.高等数学-两个重要的极限定理