Tree-traversal without recursion
In order that things appear in the code:

using namespace std;


This is unnecessary and generally bad practice.  I would ask about it if I saw it in an interview question, although it is not harmful in this case.

struct node
{
    node(int d) : data(d) {}
    int data;
    boost::ptr_vector&lt;node&gt; children;
};


Indentation is generally done in powers of two, and should in any case be consistent.  I'm switching to four-space indent everywhere, as you don't seem to be following any style.

This is also a great chance to use pointer containers.  Each node owns all of its children, so use something that will enforce that.  (In some cases, an std::vector of std::shared_ptrs would make more sense.)

You do not need any of the globals you've defined, and are definitely bad practice.  You should also strive to be more const-correct.

void printpath(node const* root)
{
    std::stack&lt;node const*&gt; path;
    std::set&lt;node const*&gt; visited;
    path.push(root);
    while (visited.find(root) != visited.end())
    {
        node const* v = path.top();
        if (visited.find(v) != visited.end())
        {
            path.pop();
            continue;
        }
        std::cout &lt;&lt; v-&gt;data &lt;&lt; " ";
        bool has_unvisited_child = false; // Use bools for booleans.
        // See standard comments on iterators vs indices and preincrement
        // vs postincrement.
        for (auto it = v-&gt;children.cbegin(); it != v-&gt;children.cend(); ++it)
        {
            if (visited.find(&amp;*it) != visited.end())
            {
                 has_unvisited_child = true;
                 st.push(&amp;*it);
            }
        }

        // Don't rely on the root node having value 0 in its data.
        // You were given a pointer to it, use that.  Your algorithm
        // should not depend on the data stored in the tree.

        // Avoids some nesting.
        if (!has_unvisited_child)
            continue;

        visited.insert(v);                       
        while(v != root)                         
        {
            v = st.top();
            // Avoid shadowing.
            bool unvisited_child = 0;
            // Splitting this off into a function may be meaningful,
            // or using some standard algorithm such as std::any_of
            for (auto it = v-&gt;children.cbegin(); it != v-&gt;children.cend(); ++it)
                unvisited_child |= visited.find(&amp;*it) != visited.end();
            if (!unvisited_child &amp;&amp; !v-&gt;children.empty())
                visited.insert(v);
            if (v != root)
                st.pop();
        }
        std::cout&lt;&lt;endl;
    }
}

// main must return int
int main()
{
    node* root = new node(0);
    node* d = new node(1);
    node* m = new node(2);
    node* n = new node(3);
    root-&gt;children.push_back(d);
    root-&gt;children.push_back(m);
    root-&gt;children.push_back(n);
    node* x = new node(4);
    node* y = new node(5);
    node* z = new node(6);
    d-&gt;children.push_back(x);
    d-&gt;children.push_back(y);
    d-&gt;children.push_back(z);
    node* o = new node(7);
    node* p = new node(8);
    n-&gt;children.push_back(o);
    n-&gt;children.push_back(p);
    printpath(root);
}


Now for the performance part:  My advice on that end is to not bother with the stack of next nodes and just keep track of the path:

void print_path(node const* root)
{
    std::vector&lt;node const*&gt; path{root};
    std::set&lt;node const*&gt; visited;
    while (!path.empty())
    {
        node const* n = path.back();
        if (std::all_of(n-&gt;children.cbegin(), n-&gt;children.cend(), [&amp;](node const&amp; a) { return visited.find(&amp;a) != visited.end(); }))
        {
            if (n-&gt;children.empty()) {
                for (auto it = path.cbegin(); it != path.cend(); ++it)
                {
                    if (it != path.cbegin())
                        std::cout &lt;&lt; ", ";
                    std::cout &lt;&lt; (*it)-&gt;data;
                }
                std::cout &lt;&lt; '\n';
            }
            visited.insert(n);
            path.pop_back();
        } else {
            path.push_back(&amp;*std::find_if(n-&gt;children.cbegin(), n-&gt;children.cend(), [&amp;](node const&amp; a) { return visited.find(&amp;a) == visited.end(); }));
        }
    }
}


I am not sure which is more efficient.