开发者

UVA #10410 Tree Reconstruction [closed]

Closed. This question needs debugging details. It is not currently accepting answers.

Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.

Closed 2 years ago.

Improve this question 开发者_运维百科

I have worked on UVA 10410 Tree Reconstruction several days. But I can't get the correct answer unitl now.

I have used an algorithm similar to the one which we always use to recovery a binary tree through the preorder traversal and the inorder traversal. But it can't work.

Can anyone help me? Thanks in advance.


I think I have the hang of it. I don't pretend it's efficient though.

Let's look at the first 3 digits of the BFS output:

4 3 5

We are in one of these situations:

  4         4
/  \   OR   |
3  5        3
x  x        |
            5
            x

What is the DFS for those 2 cases ?

  • 4 3 (3s-children) 5 (5s-children)
  • 4 3 5 (5s-children)

Quick note: if 3 does not have any child, then it's impossible to tell the two apart...

If we consider that the problem is decidable, then it's a matter of knowing if 5 follows 3 in the DFS representation.

  • If it does: it's a linear composition
  • If it does not then you go recursive: 4 has 2 children 3 and 5 and you can easily identify the subtree from the DFS representation. Then extract (preserving order) the BFS representation of these subtrees from the BFS you had and recurse :)

It seems fairly far from optimal, but I am a bit more worried about the undecidability.

Is there a constraint in expression-parse trees which states that once you have a node that only has one child none of the nodes in the subtree it represents can have more than one ?


"Note that when a parent was expanded the children were traversed in ascending order." This sentence is very important!

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

struct Node
{
    int value;
    Node *child; //left child
    Node *sibling; //right sibling

    Node(int v)
    {
        value = v;
        child = NULL;
        sibling = NULL;
    }
};

void BuildTree(Node *&root,vector<int> bfs,vector<int> dfs)
{
    root = NULL;
    if(bfs.size() == 1)
        root = new Node(bfs[0]);
    if(bfs.size() > 1)
    {
        root = new Node(bfs[0]);

        vector<int> candidate; //store candidate childs
        unsigned i;
        for(i = 1; i < bfs.size(); i++)
        {
            if(bfs[i] >= bfs[1])
                candidate.push_back(bfs[i]);
            else
                break;
        }

        //remove the non-candidate node
        int boundOfChild = candidate.size() - 1;
        for(i = candidate.size() - 1; i >= 1; i--)
        {
            vector<int>::iterator it1;
            vector<int>::iterator it2;
            it1 = find(dfs.begin(),dfs.end(),candidate[i]);
            it2 = find(dfs.begin(),dfs.end(),candidate[i - 1]);
            if(it1 < it2)
                boundOfChild = i;
        }
        if(boundOfChild != candidate.size() - 1)
            candidate.erase(candidate.begin() + boundOfChild,candidate.end());

        //get every child's bfs and dfs
        for(i = candidate.size(); i >= 1; i--)
        {
            vector<int>::iterator it1;
            vector<int>::iterator it2;
            if(i == candidate.size())
            {
                it1 = find(dfs.begin(),dfs.end(),candidate[i - 1]);
                it2 = dfs.end();
            }
            else
            {
                it1 = find(dfs.begin(),dfs.end(),candidate[i - 1]);
                it2 = find(dfs.begin(),dfs.end(),candidate[i]);
            }

            vector<int> tmp_dfs(it1,it2);
            vector<int> tmp_bfs;
            for(vector<int>::iterator it = bfs.begin(); it < bfs.end(); it++)
            {
                if(find(tmp_dfs.begin(),tmp_dfs.end(),*it) != tmp_dfs.end())
                    tmp_bfs.push_back(*it);
            }

            Node *tmp = root->child;
            BuildTree(root->child,tmp_bfs,tmp_dfs);
            root->child->sibling = tmp;
        }
    }
}

void PrintTree(Node *root)
{
    if(root == NULL)
        return;
    queue<Node*> Q;
    Q.push(root);
    while(!Q.empty())
    {
        Node *tmp = Q.front();
        Q.pop();
        cout << tmp->value << ": ";
        tmp = tmp->child;
        while(tmp)
        {
            cout << tmp->value << ",";
            Q.push(tmp);
            tmp = tmp->sibling;
        }
        cout << endl;
    }
}

//just test case
int BFS[] = {7,8,12,4,5,1,6,11,2,3,10,9,13,14};
int DFS[] = {7,8,4,5,2,3,12,1,6,10,14,11,9,13};

int main()
{
    vector<int> vBFS(BFS,BFS + sizeof(BFS) / sizeof(int));
    vector<int> vDFS(DFS,DFS + sizeof(DFS) / sizeof(int));

    Node *root = NULL;
    BuildTree(root,vBFS,vDFS);    
    PrintTree(root);

    return 0;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜