typename property_traits<ComponentMap>::value_type
strong_components_impl
(const Graph& g,    // Input
 ComponentMap comp, // Output
 // Internal record keeping
 RootMap root,
 DiscoverTime discover_time,
 const bgl_named_params<P, T, R>& params)
{
    typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
    BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept<ComponentMap, Vertex> ));
    BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept<RootMap, Vertex> ));
    typedef typename property_traits<RootMap>::value_type RootV;
    BOOST_CONCEPT_ASSERT(( ConvertibleConcept<RootV, Vertex> ));
    BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept<DiscoverTime, Vertex> ));

    typename property_traits<ComponentMap>::value_type total = 0;

    std::stack<Vertex> s;
    detail::tarjan_scc_visitor<ComponentMap, RootMap, DiscoverTime,
           std::stack<Vertex> >
           vis(comp, root, discover_time, total, s);
    depth_first_search(g, params.visitor(vis));
    return total;
}
 inline void prim_minimum_spanning_tree
   (const VertexListGraph& g,
    PredecessorMap p_map,
    const bgl_named_params<P,T,R>& params)
 {
   detail::prim_mst_impl
     (g, 
      choose_param(get_param(params, root_vertex_t()), *vertices(g).first), 
      params.predecessor_map(p_map),
      choose_const_pmap(get_param(params, edge_weight), g, edge_weight));
 }
void maximum_flow_path(Graph& g,
                       typename graph_traits<Graph>::vertex_descriptor s,
                       const bgl_named_params<P, T, R>& params) {
    typedef typename property_traits<typename property_map<Graph, edge_weight_t>::type>::value_type WeightDataType;
    dijkstra_shortest_paths(g,
                            s,
                            params.distance_compare(std::greater<WeightDataType>()).
                                    distance_combine([](WeightDataType a, WeightDataType b) { return std::min(a, b); }).
                                    distance_inf(WeightDataType()).
                                    distance_zero(std::numeric_limits<WeightDataType>::max())
    );
}
 inline void
 prim_mst_impl(const Graph& G,
               typename graph_traits<Graph>::vertex_descriptor s,
               const bgl_named_params<P,T,R>& params,
               Weight)
 {
   typedef typename property_traits<Weight>::value_type W;
   std::less<W> compare;
   detail::_project2nd<W,W> combine;
   dijkstra_shortest_paths(G, s, params.distance_compare(compare).
                           distance_combine(combine));
 }
void maximum_flow_algorithm(Graph& g,
                                typename graph_traits<Graph>::vertex_descriptor s,
                                const bgl_named_params<P, T, R>& params) {
    typedef typename property_traits<typename property_map<Graph, edge_weight_t>::type>::value_type WT;

//    dummy_property_map p_map;
//    typedef decltype(choose_param(get_param(params, vertex_distance), p_map)) DistanceMap;
//    std::cout<< typeid(property_map<Graph, edge_weight_t>).name() << std::endl;
//    typedef typename property_traits<DistanceMap>::value_type DT;

    dijkstra_shortest_paths(g, s, params.distance_compare(std::greater<WT>()).
            distance_combine([](WT a, WT b) { return std::min(a, b); }).
            distance_inf(WT()).
            distance_zero(std::numeric_limits<WT>::max()));

}
 void topological_sort(VertexListGraph& g, OutputIterator result,
                       const bgl_named_params<P, T, R>& params)
 {
   typedef topo_sort_visitor<OutputIterator> TopoVisitor;
   depth_first_search(g, params.visitor(TopoVisitor(result)));
 }