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. Python-10行代码实现3个数据可视化

    阅读本文约“1分钟” 最近将Python作为第二编程语言,进行了了解与学习,可以说它的包是很强大的.这次的demo仅仅不到10行代码就可以实现三个数据可视化的小实例. 我们将要使用到matplotli ...

  2. mongodb与java整合

    mongodb与java整合需要用到mongodb驱动,如果是maven环境,则添加如下倚赖: <dependency> <groupId>org.mongodb</gr ...

  3. Java简单介绍及Java生态

    核心思想:面向对象编程,继承,高兼容(代码移植性强),开源,避免重复造轮子(使用mybatis,spring,redis等技术只需要将jar包依赖添加到项目中即可,jar包内就是技术核心代码,而这些框 ...

  4. Java win7或 xp下配置JDK环境变量

    JAVA win7或 xp下配置JDK环境变量 by:授客 QQ:1033553122 1.安装JDK,安装过程中可以自定义安装目录等信息,例如我们选择安装目录为D:\java\jdk1.5.0_08 ...

  5. 微信wx.request

    官方 wx.request 代码,Post 没成功过,使用Get 方式成功了. wx.request({ url: 'test.php', //仅为示例,并非真实的接口地址 data: { x: '' ...

  6. 鼠标滑过侧边弹出内容(JS)

    效果展示 实现原理 1. html结构: <div id="contain"> <span id="share">分享</span ...

  7. elementUI vue tree input 懒加载 输入下拉树型示例 点击其他区域关闭自定义div

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  8. POJ 2311 Cutting Game(二维SG+Multi-Nim)

    Cutting Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4798   Accepted: 1756 Desc ...

  9. JMeter 配置元件之HTTP Cookie Manager 介绍

    配置元件之HTTP Cookie Manager 介绍   by:授客 QQ:1033553122 测试环境 apache-jmeter-2.13 1.   Cookie管理器介绍 Cookie Ma ...

  10. (网页)HTMl5的sessionStorage和localStorage

    百度上百度的,记录一下: html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage. sessionStorage用于本地存储一个会话(sessi ...