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; }