Учитывая следующий график:
использование boost
дает следующее перечисление dfs графика:
order of discovery: 0 1 2 3 4 5 6
order of finish: 2 3 1 0 6 5 4
Код, который производит это:
бгл.ч
#pragma once
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/range/irange.hpp>
#include <boost/pending/indirect_cmp.hpp>
using namespace boost;
typedef adjacency_list_traits<vecS, vecS, directedS> Traits;
typedef adjacency_list<
vecS, vecS, directedS,
property<
vertex_name_t, std::string,
property<vertex_index_t, int,
property<vertex_color_t, boost::default_color_type,
property<vertex_distance_t, double,
property<vertex_predecessor_t, Traits::edge_descriptor>
> > > >,
property<
edge_index_t, int,
property<edge_capacity_t, double,
property<edge_weight_t, double,
property<edge_residual_capacity_t, double,
property<edge_reverse_t, Traits::edge_descriptor>
> > > > >
Graph;
typedef graph_traits < Graph >::vertices_size_type size_type;
template < typename TimeMap > class dfs_time_visitor:public default_dfs_visitor {
typedef typename property_traits < TimeMap >::value_type T;
public:
dfs_time_visitor(TimeMap dmap, TimeMap fmap, T & t)
: m_dtimemap(dmap), m_ftimemap(fmap), m_time(t) {
}
template < typename Vertex, typename Graph >
void discover_vertex(Vertex u, const Graph & g) const
{
put(m_dtimemap, u, m_time++);
}
template < typename Vertex, typename Graph >
void finish_vertex(Vertex u, const Graph & g) const
{
put(m_ftimemap, u, m_time++);
}
TimeMap m_dtimemap;
TimeMap m_ftimemap;
T & m_time;
};
typedef
iterator_property_map<std::vector<size_type>::iterator,
property_map<Graph, vertex_index_t>::const_type>
time_pm_type;
class Dfsgraph{
public:
void addvertex();
void addedge(int f, int t);
void rundfs();
private:
Graph g;
std::vector < size_type > dtime;
std::vector < size_type > ftime;
};
бгл.cpp
#include "bgl.h"
#include <stdio.h>//for printf
void Dfsgraph::addvertex(){
add_vertex(g);
dtime.push_back(0);
ftime.push_back(0);
}
void Dfsgraph::addedge(int f, int to){
add_edge(f, to, g);
}
void Dfsgraph::rundfs(){
time_pm_type dtime_pm(dtime.begin(), get(vertex_index, g));
time_pm_type ftime_pm(ftime.begin(), get(vertex_index, g));
size_type t = 0;
dfs_time_visitor < time_pm_type >vis(dtime_pm, ftime_pm, t);
depth_first_search(g, visitor(vis));
// use std::sort to order the vertices by their discover time
std::vector < size_type > discover_order(num_vertices(g));
integer_range < size_type > r(0, num_vertices(g));
std::copy(r.begin(), r.end(), discover_order.begin());
std::sort(discover_order.begin(), discover_order.end(),
indirect_cmp < time_pm_type, std::less < size_type > >(dtime_pm));
printf("order of discovery: ");
int i;
for (i = 0; i < num_vertices(g); ++i)
printf(" %d ", discover_order[i]);
std::vector < size_type > finish_order(num_vertices(g));
std::copy(r.begin(), r.end(), finish_order.begin());
std::sort(finish_order.begin(), finish_order.end(),indirect_cmp < time_pm_type, std::less < size_type > >(ftime_pm));
printf("\norder of finish: ");
for (i = 0; i < num_vertices(g); ++i)
printf(" %d ", finish_order[i]);
printf("\n");
}
int main(){
Dfsgraph g;
for(int nd = 0; nd < 7; nd++)
g.addvertex();
g.addedge(0,1);
g.addedge(1,2);
g.addedge(1,3);
g.addedge(4,5);
g.addedge(5,3);
g.addedge(5,6);
g.rundfs();
return 0;
}
Я хотел бы перечислить все полные пути от корневых узлов (тех, у которых нет входящей дуги) до соответствующих конечных узлов (тех, у которых нет исходящей дуги).То есть я бы хотел перечислить:
0->1->2
0->1->3
4->5->3
4->5->6
Q1.Возможно ли это с помощью готовых библиотечных функций, предлагаемых boost
?
Q2.Если нет, каковы эффективные способы сделать это с нуля?