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. 【Java每日一题】20170223

    20170222问题解析请点击今日问题下方的“[Java每日一题]20170223”查看(问题解析在公众号首发,公众号ID:weknow619) package Feb2017; public cla ...

  2. SpringBoot快速开始Hello World

    介绍 Spring Boot跟Spring MVC不太一样,Spring MVC建新项目的时候是要配置很多东西的,而Spring Boot讲究的是快速,提供了很多默认配置,所以新建一个项目不需要手动配 ...

  3. JSJ—类与对象

    当你在设计类时,要记得对象时靠类的模型塑造出来的,你可以这样看: ——对象是已知事物 ——对象会执行的动作 对象本身已知的事物称为实例变量,它们代表对象的状态(数据),且该类型的每一个对象都会独立的拥 ...

  4. [小知识点] react 性能

    场景: jsx 绑定方法 方法有3种 1: // 在html中,使用箭头函数,自动绑定this class SearchHistory extends React.Component {      c ...

  5. VMWAR-workstatuon

    https://blog.csdn.net/felix__h/article/details/82853501 链接中的秘钥可用~感谢原文作者 下载安装: 官网下载地址:https://www.vmw ...

  6. vue单页应用添加百度统计

    前言 申请百度统计后,会得到一段JS代码,需要插入到每个网页中去,在Vue.js项目首先想到的可能就是,把统计代码插入到index.html入口文件中,这样就全局插入,每个页面就都有了;这样做就涉及到 ...

  7. BZOJ2783: [JLOI2012]树(树上前缀和+set)

    Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 1215  Solved: 768[Submit][Status][Discuss] Descriptio ...

  8. 关于TensorFlow你需要了解的9件事

    关于TensorFlow你需要了解的9件事 https://mp.weixin.qq.com/s/cEQAdLnueMEj0OQZtYvcuw 摘要:本文对近期在旧金山举办的谷歌 Cloud Next ...

  9. spring boot mybatis 打成可执行jar包后启动UnsatisfiedDependencyException异常

    我的spring boot + mybatis项目在idea里面执行正常,但发布测试环境打成可执行jar包后就启动失败,提示错误如下: [ ERROR] [2018-08-30 17:23:48] o ...

  10. leetcode-58.最后一个单词的长度

    leetcode-58.最后一个单词的长度 题意 给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度. 如果不存在最后一个单词,请返回 0 . 说明:一个单词是指由字母组成,但 ...