zoukankan      html  css  js  c++  java
  • Uva 10410 Tree Reconstruction

    题目大意是根据输入的dfs,bfs重建一棵树并输出他的节点。

    这道题一开始做的时候没什么思路,原先是想的根据dfs,bfs递归求解,但没有想出来。

    后来参考网上的思路,找到了这道题解决的关键所在:dfs和bfs得到的序列中有一个共同特点,每一个节点的相邻节点可能是兄弟节点,可能是孩子节点,也可能都不是。问题关键是判断他是什么类型的节点,这样得到的树才唯一。因此解决这道题需要使用一个栈来求解。

    根据bfs,我们可以得到节点之间的距离。

    如果dfs中两节点相邻,代表他们是兄弟节点或者子节点或者其他。把第一个节点当做根节点,根据bfs序列判断根节点和另一个节点的距离,如果距离为负,代表既不是兄弟节点,也不是子节点;如果距离为正且相邻,代表是兄弟节点;否则是孩子节点。这样对于任何一个新加入的节点,总可以在栈中找到他的根节点。从而计算出结果来。

    大体我能理解到这个程度,下边是我的实现代码

     1 #include <cstdio>
     2 #include <vector>
     3 #include <algorithm>
     4 #include <stack>
     5 using namespace std;
     6 const int maxn = 1000 + 10;
     7 int main(){
     8     int n;
     9     vector<int> g[maxn];
    10     int pos[maxn];
    11     while(~scanf("%d",&n)){
    12         for(int i=1;i<=n;i++){
    13             int x;
    14             scanf("%d",&x);
    15             g[i].clear();
    16             pos[x] = i;
    17         }
    18         
    19         int root;
    20         stack<int> sta;
    21         scanf("%d",&root);
    22         sta.push(root);
    23         for(int i=1;i<n;i++){
    24             int x;
    25             scanf("%d",&x);
    26             while(true){
    27                 int u = sta.top();
    28                 if(u==root||pos[u]+1 <pos[x])
    29                 {
    30                     g[u].push_back(x);
    31                     sta.push(x);
    32                     break;
    33                 }
    34                 else{
    35                     sta.pop();
    36                 }
    37             }
    38         }
    39         for(int i=1;i<=n;i++){
    40             printf("%d:",i);
    41             sort(g[i].begin(),g[i].end());
    42             for(int d : g[i]){
    43                 printf(" %d",d);
    44             }
    45             puts("");
    46         }
    47 
    48     }
    49     return 0;
    50 }

     另外,

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

    这篇博客加深了我对这题的理解。

    前边说到相邻序列的三种关系,这篇博客中加了一种讨论

    当两节点相邻,但当前节点小于根节点,就代表当前节点是根节点的子节点,要着重注意的是相邻的条件。

    但他说的第四条那个等效问题我还不是很明白。以后再回过头来看看。

  • 相关阅读:
    centos6.5 mysql配置整理
    第四章 Web表单
    第三章 模板
    第二章 程序的基本结构
    第一章 安装
    常见网络错误代码(转)
    微软消息队列MessageQueue(MQ)
    基于.NET平台常用的框架整理(转)
    Sqlserver更新数据表xml类型字段内容某个节点值的脚本
    正则表达式_基础知识集合
  • 原文地址:https://www.cnblogs.com/Wade-/p/6358859.html
Copyright © 2011-2022 走看看