• UVA10410 树重建 Tree Reconstruction


    知识点:树的遍历

    这个题考察的是对树的dfs和bfs遍历的理解,洛谷里面有一篇题解讲的特别清楚,我就是按照那种方法做的,

    总的思路是用dfs序为基础,用bfs序为辅助来求,在dfs序上每个节点的父亲一定在这个节点的前面,那么我们就从dfs序上每个节点向前遍历找它的父亲,然后我们记录每个节点在bfs序列里面的位置,用来作为辅助,

    假设当前节点是v,我们在dfs序里面从它向前遍历,找到第一个bfs序列位置小于v在bfs序列位置的节点,设为u,那么u只可能是v的左边的兄弟或者父亲,这是至关重要的一点,这个想明白了这个题就完成了一半,因为dfs序的特性,我们开始从v向前遍历的时候,一开始就是在v的父亲的子树里面遍历的,肯定不会超出这个范围,因为上面说了是第一个,在v的父亲的子树里面,一定有bfs序位置小于v的元素,可能直接就是父亲节点,如果v有左边的兄弟节点的话,那么就是兄弟节点,这就是我的理解的方式,洛谷的题解给了另外的理解方式

    接下来,开始分类讨论判断,u在bfs序列里面的位置+1小于v在bfs序列里面的位置,也就是u和v在bfs序列里面不挨着,那么u一定是父亲,因为兄弟在bfs序列里面是一定挨着的

    else,如果u大于v,那么u是父亲,因为题目说了节点的孩子是从小到大遍历的,如果是u小于v,那么u还是可能是兄弟或者父亲,具体的说分两种情况,1,如果没有深度和u相同且权值大于u的节点,和深度和v相同且父亲权值小于u的节点,这种情况,u是v的父亲或者兄弟都满足题意,都行,自己距离画图就知道,2,除了情况1,u只能是兄弟节点,所以逻辑很清晰了,任何时候,我们把这个bfs序位置+1等于v的bfs序位置的节点,当成是兄弟都不会出错的,只有情况1的时候,它即可能是兄弟也可能是父亲,但是那样显然是得不偿失的,因为我们要判断情况1就很困难,现有的条件应该是做不到的,就算是情况1判断出来了,那么u还是可能是兄弟或者父亲,还是可以选兄弟,所以不如一开始,在当前分支下面,一律认为u是兄弟,那么兄弟的父亲是相同的,v的父亲也就找到了

    1. #include
    2. using namespace std;
    3. const int N = 1005;
    4. int main() {
    5. int n;
    6. while (cin >> n) {
    7. int a[N], b[N], bfs[N];
    8. for (int i = 1; i <= n; i++) {
    9. cin >> a[i];
    10. bfs[a[i]] = i;
    11. }
    12. for (int i = 1; i <= n; i++) {
    13. cin >> b[i];
    14. }
    15. vector<int> v[N];
    16. int fa[N];
    17. v[b[1]].push_back(b[2]);
    18. fa[b[2]] = b[1];
    19. for (int i = 3; i <= n; i++) {
    20. int j = i - 1;
    21. while (j >= 1 && bfs[b[j]] > bfs[b[i]]) j--;
    22. if (bfs[b[j]] + 1 < bfs[b[i]]) {
    23. v[b[j]].push_back(b[i]);
    24. fa[b[i]] = b[j];
    25. } else {
    26. if (b[j] > b[i]) {
    27. v[b[j]].push_back(b[i]);
    28. fa[b[i]] = b[j];
    29. } else {
    30. v[fa[b[j]]].push_back(b[i]);
    31. fa[b[i]] = fa[b[j]];
    32. }
    33. }
    34. }
    35. for (int i = 1; i <= n; i++) {
    36. cout << i << ':';
    37. for (int j = 0; j < (int) v[i].size(); j++) {
    38. cout << ' ' << v[i][j];
    39. }
    40. cout << '\n';
    41. }
    42. }
    43. return 0;
    44. }

  • 相关阅读:
    Handler消息机制,postDelayed会造成线程阻塞吗?对内存有什么影响?
    【T+】win10/win11系统安装畅捷通T+Cloud专属云18.0
    Vue Table表格动态展示列 Table表格自定义显示列 动态设置列是否展示 可拖拽设置列的显示顺序
    1078. Bigram 分词
    学生HTML网页作业:基于HTML+CSS+JavaScript画家企业8页
    【LabVIEW 】串口如何读取长度不一致的字符串
    基于SSH开发学生公寓管理系统
    Redis常见场景问题和解决方案
    Spring Cloud【实现用户鉴权(什么是JWT、JWT原理、用户微服务、JWT工具类、用户服务实现JWT鉴权)】(八)
    xinput1_4.dll丢失怎么修复?修复方法分享
  • 原文地址:https://blog.csdn.net/m0_73035684/article/details/128076131