boost 图形库文档定义了一个 BFS Visitor concept 声明
用户可以使用 BFS 访问者接口定义一个类,并将该类的一个对象传递给 breadth_first_search(),从而增加在图搜索期间采取的操作。
基于此和bfs.cpp example,完成您所要求的首选方法是继承boost::visitor 或boost::default_bfs_visitor 并覆盖其中的一个或多个
initialize_vertex
discover_vertex
examine_vertex
examine_edge
tree_edge
non_tree_edge
gray_target
black_target
finish_vertex
对于您的用例,我认为子类化 boost::default_bfs_visitor 并覆盖 discover_vertex 是最合适的:
discover_vertex(s, g)
第一次遇到顶点时调用。 s 是 boost::graph_traits<Graph>::vertex_descriptor 类型的对象,g 是 Graph 类型的对象。
这里是一个确切的示例,通过适当处理 std::queue 对象来记录顶点。
#include <queue>
#include <iostream>
#include <boost/graph/visitors.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
typedef boost::property<boost::edge_weight_t, unsigned int> EdgeWeightProperty;
typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS,
boost::no_property, EdgeWeightProperty> Graph;
class BFSVisitor : public boost::default_bfs_visitor {
public:
BFSVisitor(std::queue<Graph::vertex_descriptor>& _visited) : visited(_visited){}
void discover_vertex(Graph::vertex_descriptor s, const Graph &g) { visited.push(s); }
std::queue<Graph::vertex_descriptor>& visited;
};
int main() {
Graph g;
boost::add_edge(0,1,6,g);
boost::add_edge(1,2,6,g);
boost::add_edge(2,3,6,g);
boost::add_edge(3,1,6,g);
boost::add_edge(3,4,6,g);
Graph::vertex_descriptor s = *(boost::vertices(g).first);
std::queue<Graph::vertex_descriptor> q;
BFSVisitor vis(q);
boost::breadth_first_search(g, s, boost::visitor(vis));
while (!vis.visited.empty()) {
std::cout << vis.visited.front() << std::endl;
vis.visited.pop();
}
}
哪个会输出
0
1
2
3
4
注意 — Boost 期望图表从顶点 0 开始,而不是 1 - 因此这条线
boost::add_edge(0,1,6,g);
如果从顶点1 开始,将没有输出。