[bfs和dfs的性质] Tree Reconstruction UVa10410

题目描述

给定一个有 n 0 < n <= 1000 个节点的树的bfs序列和dfs序列,重建这棵树,输出每个节点的子节点。无论以何种方式,在遍历树时总是先访问其最小的子节点。

题解

最开始,想用递归的方式重建树。但遇到的问题一是分解子bfs序列和子dfs序列比较麻烦,二是确定层数比较难确定。
之后,参考前辈的做法。是用一个栈保存当前节点,通过遍历dfs序列,确定其子节点。需要注意的是,生成bfs和dfs序列时总是先访问最小的节点。所以当前根节点与当前节点的距离为1但当前节点的值小于根节点时,两个节点不应是兄弟关系。而当不小于时,则两节点时兄弟关系。

AC代码

#include <cstdio>
#include <vector>
#include <stack>
using namespace std;

const int maxn = 1000 + 1;

vector<int> ans[maxn];
int pos[maxn];

int main(){
    int n;
    while(scanf("%d", &n) != EOF){
        int x;
        for(int i = 1; i<=n; i++){
            scanf("%d", &x);
            ans[i].clear();
            pos[x] = i;
        }
        int rot;
        scanf("%d", &rot);
        stack<int> root;
        root.push(rot);
        for(int i = 1; i<n; ++i){
            scanf("%d", &x);
            while(1){
                int rt = root.top();
                if(rt == rot || pos[rt]+1 < pos[x] || (pos[rt]+1 == pos[x] && rt > x)){
                    ans[rt].push_back(x);
                    root.push(x);
                    break;
                }
                else root.pop();
            }
        }

        for(int i = 1; i<=n; ++i){
            printf("%d:", i);
            for(int j = 0, k =ans[i].size(); j<k; ++j)
                printf(" %d", ans[i][j]);
            printf("\n");
        }
    }
}

猜你喜欢

转载自blog.csdn.net/loyxCCS/article/details/80296150