UVA-10410 Tree Reconstruction (树重建)

题目大意:给出对一棵树的BFS遍历序列和DFS遍历序列,求出每一个节点的子节点。

题目分析:在BFS的序列中,子节点的下标一定比父节点的下标至少大1(根节点与第一个子节点除外),即pos[fa]+1<pos[son]。当节点u、v满足pos[u]+1==pos[v]时,u和v为兄弟节点。只需循环一遍DFS序列便可递归的找出所有节点的子节点。循环一遍DFS序列实际上就是一个深搜的过程。

 

代码如下:

# include<iostream>
# include<cstdio>
# include<vector>
# include<stack>
# include<cstring>
# include<algorithm>
using namespace std;

vector<int>v[1001];
int pos[1001];
stack<int>s;

int main()
{
    int n,a;
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;++i){
            scanf("%d",&a);
            v[i].clear();
            pos[a]=i;
        }

        while(!s.empty())
            s.pop();
        int root;
        scanf("%d",&root);
        s.push(root);
        for(int i=1;i<n;++i){
            scanf("%d",&a);
            while(1){
                int u=s.top();
                if(u==root||pos[u]+1<pos[a]){///pos[u]+1==pos[a]时,u和a为兄弟节点
                    v[u].push_back(a);
                    s.push(a);///深搜又加深了一层
                    break;///一旦找到a的父节点便找序列中的下一个节点的父节点
                }else
                    s.pop();
            }
        }

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

  

posted @ 2015-10-07 20:50  20143605  阅读(615)  评论(0编辑  收藏  举报