1. 程式人生 > >UVA - 10410 Tree Reconstruction (根據dfs序和bfs序恢復一顆樹)

UVA - 10410 Tree Reconstruction (根據dfs序和bfs序恢復一顆樹)

bsp int clu pan n) printf pri 完全 scanf

題意:

技術分享

分析:

這題一開始完全沒有思路, 一直沒有找出規律。

參考了http://www.cnblogs.com/Wade-/p/6358859.html 和 http://www.cnblogs.com/jerryRey/p/4622927.html

在dfs序列中,相鄰的兩個結點u,v之間(dfs_pos(u) + 1 = dfs_pos(v)),有父子,兄弟,其他3種關系。

父子關系:在bfs中u,v並不是相鄰, bfs_pos(v) > bfs_pos(u) , 那麽u為v父親, v為u兒子。

兄弟關系:在bfs中, bfs(u) + 1 = bfs(v) (相鄰).

其他關系:其實就是沒有關系, bfs_pos(u) >= bfs_pos(v)

只要知道這3個關系, 就可以找出每個節點的父親了, 用棧去模擬

#include <bits/stdc++.h>
using namespace std;
vector<int> son[1007];
int n;
int pos[1007];
int main(){
    while(~scanf("%d", &n)){
        for(int i = 0; i < n; i++){
            int t;
            scanf("%d", &t);
            pos[t] = i;
        }
        stack
<int> s; int root; scanf("%d", &root); s.push(root); for(int i = 0; i < n - 1;i++){ int x; scanf("%d", &x); for(;;){ int u = s.top(); if(pos[u] + 1 < pos[x] || u == root){//如果u與x不相鄰而且pos(x) > pos(u)(bfs中序列, 根除外)
son[u].push_back(x); // 那麽u一定是x的父親 s.push(x); break; } else{ s.pop(); } } } for(int i = 1; i <= n; i++){ printf("%d:", i); sort(son[i].begin(), son[i].end()); for(int j = 0; j < son[i].size(); j++){ printf(" %d", son[i][j]); } son[i].resize(0); puts(""); } } }

UVA - 10410 Tree Reconstruction (根據dfs序和bfs序恢復一顆樹)