Search code examples
c++algorithmdepth-first-searchshortest-path

"Extended" depth-first search in C++


I know how to implement depth-first search algorithm in C++, but I need an "extended version". So, I have a map

map<int, map<int,int> > tree;

that for any vertex it returns a map with adjacent vertices as keys and (important for my program) edge indexes as values. The root of the tree is first (1) vertex. So, here is my code:

stack<int> s;
for(const auto &pair : tree[1]) s.push(pair.first);
while(!s.empty()) {
    if(!visited[s.top()]) {    //it's just bool array
        roads[s.top()] = {0}; // ???
        for(const auto &pair : tree[s.top()]) s.push(pair.first);
    }
    s.pop();
}

What I need to do is create a vector of vectors in which, for every vertex, I'll have a complete path (expressed as edge indexes).

For example for graph like that:

       1
      /  \
(i=2)/    \(i=1)
    /      \
   2       3
           /\
          /  \
    (i=3)/    \(i=4)
        /      \
       4        5

I would like to have something like this:

vector< vector<int> > roads = {{},{},{2},{1},{1,3},{1,4};

because roads[0] does not exist, roads[1] too, and for every other we have path expressed as edge indexes.

EDIT

In other words what I want to do: For every vertex in a given tree I want to know a path from root to this vertex. Every edge in this tree has its own number, so path would be expressed as a vector or set (for simplicity's sake, I don't care at all about the order of edges).


Solution

  • "graph with no cycles" is also known as a tree.

    You want to have a list with all the sequences of edge labels that represent a path from root to some vertex?

    Pseudocode for a traversal (I guess this would qualify as a preorder traversal):

    void collect(node, //current node
        labels, //labels of edges leading to node
        &paths //all the paths collected so far, writeable, contains results
    ) {
        paths.add(labels);
        foreach ((neighbor_node, edge_name) in (unvisited neighbors of node)) {
            labels.add(edge_name);
            collect(neighbor_node, labels, paths);
            labels.remove(edge_name);                
        }
    }
    
    start with collect(root, empty_list, empty_list);