Problem UVA10410-Tree Reconstruction

Accept:708  Submit:4330

Time Limit: 3000 mSec

Problem Description

You have just finished a compiler design homework question where you had to find the parse tree of an expression. Unfortunately you left your assignment in the library, but luckily your friend picked it up for you. Instead of e-mailing you the parse tree so that you can rewrite the solution, your friend decides to play a practical joke and sends you just the DFS and BFS trace. Rather than try to redo the entire question you decide to reconstruct the tree.

 Input

The input file contains several test cases as described below.

The first line of a input is the number n (1 <= n <= 1000) of nodes in the tree. The nodes in the tree are numbered 1, 2, ..., n. The remaining numbers are the BFS traversal followed by the DFS traversal. Note that when a parent was expanded the children were traversed in ascending order.

 Output

The output for each case should consist of n lines, one for each node. Each line should start with the node number followed by a colon followed by a list of children in ascending order. If there is more than one solution, any correct answer is acceptable.

 Sample Input

8
4 3 5 1 2 8 7 6
4 3 1 7 2 6 5 8
 
 

 Sample Ouput

1: 7
2: 6
3: 1 2
4: 3 5
5: 8
6:
7:
8:

题解:一道好题!我自己模拟的时候思路很凌乱,始终找不到一个可以实现的算法,翻看了很多题解,发现有很多题解和代码都是错的,写的比较好的博客链接如下:

http://www.cnblogs.com/jerryRey/p/4622927.html

我们先来列举两条性质:

1.在BFS序中,与点a相邻的下一个点可能有三种身份:(1)节点a的孩子 (2)节点a的第一后兄弟 (3)节点a的兄弟的孩子

2.在DFS序中,与点a相邻的下一个点可能有三种身份:(1)节点a的孩子(2)节点a的第一后兄弟(3)啥也不是(意思是说直接回到父辈及以上了)

用这两条性质我们来推出一个重要结论,设节点u,v,他们的BFS序分别设为bfs(u),bfs(v).

设这两个点在DFS序中是相邻的并且v是u的下一个节点。

结论:如果bfs(v) = bfs(u)+1 并且v>u那么,v必定可以视为u的第一后兄弟。

关键字是视为。这是相当于u,v在两个序列里都相邻,对比上文所说的三种身份,三种身份只剩两种了。如果v是u的孩子,由于二者在BFS序中相邻,因此和u在同一层的节点都遍历到了,如果u的同一层还有别的节点,那么v一定是u前面的兄弟的孩子,而此时v时u的孩子,因此,u所在的那一层只有u一个,我们把v及其子树提上来,让v变成u的后兄弟,显然不改变BFS序和DFS序,因此就证明了刚才的结论。

有了这个结论就好办多了,如果bfs(v) > bfs(u)+1那么它不可能是u的后兄弟,只能是u的孩子,证明很简单,对比三种身份,v不能是节点u的第一后兄弟,因为他们的BFS序不相邻,v不可能啥也不是,因为v的BFS序在u后面,如果v回到u的父辈及以上了,它必定出现早于u。如果bfs(v) < bfs(u)那就只能是啥也不是的情况了,这个时候怎么办,在DFS序中v回到了u的父辈及以上。那就代表着u及其子树被处理完了,忽略u就好,具体实现时弹栈就好。这里并没有把所有情况都涵盖,但是简单思考就知道那些情况对于一棵合法的树来说是不可能的。

还要注意一个细节就是栈顶元素时root时,直接加孩子,入栈。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <stack>
using namespace std; const int maxn = +;
int bfs_order[maxn];
vector<int> child[maxn]; int main()
{
//freopen("input.txt","r",stdin);
int n;
while(~scanf("%d",&n)){
int x;
for(int i = ;i <= n;i++){
child[i].clear();
scanf("%d",&x);
bfs_order[x] = i;
}
stack<int> sta;
int root;
scanf("%d",&root);
sta.push(root);
for(int i = ;i < n;i++){
scanf("%d",&x);
while(true){
int temp = sta.top();
if((bfs_order[x]>bfs_order[temp]+) || (bfs_order[x]==bfs_order[temp]+ && temp>x) || (temp==root)){
child[temp].push_back(x);
sta.push(x);
break;
}
else sta.pop();
}
}
for(int i = ; i <= n; i++) {
printf("%d:",i);
for(int j = ;j < child[i].size();j++){
printf(" %d",child[i][j]);
}
printf("\n");
}
}
return ;
}

UVA10410-Tree Reconstruction(BFS序和DFS序的性质)的更多相关文章

  1. 括号序和dfs序

    记得清北讲过括号序和dfs序,忘记了 dfs序 dfs序就是dfs的顺序,这个好记 就是在dfs遍历树的时候,将每个结点开始时记录一次,结束时记录一次 而且一个子树可以表示为连续的一段, 只有子树操作 ...

  2. 【SPOJ】10628. Count on a tree(lca+主席树+dfs序)

    http://www.spoj.com/problems/COT/ (速度很快,排到了rank6) 这题让我明白了人生T_T 我知道我为什么那么sb了. 调试一早上都在想人生. 唉. 太弱. 太弱. ...

  3. Codeforces Round #200 (Div. 1) D Water Tree 树链剖分 or dfs序

    Water Tree 给出一棵树,有三种操作: 1 x:把以x为子树的节点全部置为1 2 x:把x以及他的所有祖先全部置为0 3 x:询问节点x的值 分析: 昨晚看完题,马上想到直接树链剖分,在记录时 ...

  4. HDU5293(SummerTrainingDay13-B Tree DP + 树状数组 + dfs序)

    Tree chain problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  5. HDU 6191 Query on A Tree(可持久化Trie+DFS序)

    Query on A Tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Othe ...

  6. CodeForces 375D Tree and Queries 莫队||DFS序

    Tree and Queries 题意:有一颗以1号节点为根的树,每一个节点有一个自己的颜色,求出节点v的子数上颜色出现次数>=k的颜色种类. 题解:使用莫队处理这个问题,将树转变成DFS序区间 ...

  7. S - Query on a tree HDU - 3804 线段树+dfs序

    S - Query on a tree HDU - 3804   离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...

  8. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  9. codeforces 375D . Tree and Queries 启发式合并 || dfs序+莫队

    题目链接 一个n个节点的树, 每一个节点有一个颜色, 1是根节点. m个询问, 每个询问给出u, k. 输出u的子树中出现次数大于等于k的颜色的数量. 启发式合并, 先将输入读进来, 然后dfs完一个 ...

随机推荐

  1. JSTL_Format标记库

    JSTL_Format 一:JSTL Format标记库 如有转载,请标明出处 介绍标记属性的时候,按照顺序必须写的->带有默认值的->其他的,中间用回车隔开 在jsp问价开头加上 < ...

  2. Git如何回滚代码?

    摘要: 多年以后,你面对一个需要回滚的Git仓库,准会想起这篇博客. 某一天,用户跟我反馈,他不能分配任务了.我去看了一下Fundebug捕获的报错信息: 可知,出错原因是前端发送的请求参数有问题.这 ...

  3. HTML琐碎知识点(持续补充)

    一.table标签 <table> <thead> <tr> <th>111</th> </tr> </thead> ...

  4. 深度学习新星:GAN的基本原理、应用和走向

    深度学习新星:GAN的基本原理.应用和走向 (本文转自雷锋网,转载已获取授权,未经允许禁止转载)原文链接:http://www.leiphone.com/news/201701/Kq6FvnjgbKK ...

  5. 从零开始设计数据大屏—基于Vue ZT

    虽然已经决定这个项目用Wyn来做了,但是,了解一下如何从头开始写一个数据大屏还是挺有好玩的. ------------- 为什么要做数据大屏? 现如今的大数据逐渐发挥出了它的力量,并无形的改变着我们的 ...

  6. C#:如何使方法过时,如何否决方法

    在使用.Net Frameworkd进行开发时,经常可以在方法的智能提示ToolTip上面看到一个方法是[否决的],如图: 或者在警告里面: 甚至使用[否决的]方法的时候还会造成编译错误: 上面的这些 ...

  7. GPA简介

    GPA(Graphics Performance Analyzers)是Intel公司提供的一款免费的跨平台性能分析工具. 填写e-mail.name和country并提交后,就会收到一封有专属下载链 ...

  8. ORACLE中内部函数SYS_OP_C2C和隐式类型转换

    什么是SYS_OP_C2C呢?官方的介绍如下: SYS_OP_C2C is an internal function which does an implicit conversion of varc ...

  9. The log scan number (620023:3702:1) passed to log scan in database 'xxxx' is not valid

    昨天一台SQL Server 2008R2的数据库在凌晨5点多抛出下面告警信息: The log scan number (620023:3702:1) passed to log scan in d ...

  10. Linux如何查看YUM的安装目录

    Linux下如何查看使用YUM安装过的包的安装路径呢? 在搞清楚这个问题前,我们先来了解一下YUM. YUM(全称为 Yellow dog Updater, Modified)是一个在Fedora和R ...