Previous answer, though very useful, manages bgl tags in a bit incorrect manner, that results in redundant push_dispatch definition and may lead to build problems if other *_dispatch functions being called (in case of erase operations, e.g.).
Second confusing circumstance is that per-node edge list is substituted in adj_list template, but the unaffected whole-edge list is printed.
There are some code that presumably corrects these flaws:
// ...
template<class T> struct Sorted_vector : public std::vector<T>
{
public:
iterator insert(const T& x)
{
iterator where = std::upper_bound(begin(), end(), x, std::less<T>());
return std::vector<T>::insert(where, x);
}
};
struct vecSS{};
namespace boost{
template <class ValueType> struct container_gen<vecSS, ValueType>
{
typedef Sorted_vector<ValueType> type;
};
template <> struct parallel_edge_traits<vecSS> {
typedef allow_parallel_edge_tag type;
};
template<class T> graph_detail::vector_tag container_category(const Sorted_vector<T>&)
{
return graph_detail::vector_tag();
}
template <class T> graph_detail::unstable_tag iterator_stability(const Sorted_vector<T>&)
{
return graph_detail::unstable_tag();
}
}
typedef adjacency_list<vecSS, ...> Graph;
// ....
graph_traits<Graph>::vertex_iterator ii, ee;
for(boost::tie(ii,ee) = vertices(g);ii!=ee;++ii){
std::cout << *ii << std::endl;
graph_traits<Graph>::adjacency_iterator jj, ff;
for(boost::tie(jj,ff)=adjacent_vertices(*ii, g);jj != ff; ++jj){
std::cout << "\t -> " << *jj<<std::endl;
}
}