⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adjacency_list.hpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 HPP
📖 第 1 页 / 共 5 页
字号:
    // Did not use default argument here because that    // causes Visual C++ to get confused.    template <class Config>    inline std::pair<typename Config::edge_descriptor, bool>    add_edge(typename Config::vertex_descriptor u,              typename Config::vertex_descriptor v,             directed_graph_helper<Config>& g_)    {      typename Config::edge_property_type p;      return add_edge(u, v, p, g_);    }    //=========================================================================    // Undirected Graph Helper Class    template <class Config>    struct undirected_graph_helper;    struct undir_adj_list_traversal_tag :       public virtual vertex_list_graph_tag,      public virtual incidence_graph_tag,      public virtual adjacency_graph_tag,      public virtual edge_list_graph_tag,      public virtual bidirectional_graph_tag { };    namespace detail {      // using class with specialization for dispatch is a VC++ workaround.      template <class StoredProperty>      struct remove_undirected_edge_dispatch {        // O(E/V)        template <class edge_descriptor, class Config>        static void        apply(edge_descriptor e,               undirected_graph_helper<Config>& g_,               StoredProperty& p)        {          typedef typename Config::global_edgelist_selector EdgeListS;          BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));          typedef typename Config::graph_type graph_type;          graph_type& g = static_cast<graph_type&>(g_);                    typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g));          typename Config::OutEdgeList::iterator out_i = out_el.begin();          for (; out_i != out_el.end(); ++out_i)            if (&(*out_i).get_property() == &p) {              out_el.erase(out_i);              break;            }          typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g));          typename Config::OutEdgeList::iterator in_i = in_el.begin();          for (; in_i != in_el.end(); ++in_i)            if (&(*in_i).get_property() == &p) {              g.m_edges.erase((*in_i).get_iter());              in_el.erase(in_i);              return;            }        }      };      template <>      struct remove_undirected_edge_dispatch<no_property> {        // O(E/V)        template <class edge_descriptor, class Config>        static void        apply(edge_descriptor e,              undirected_graph_helper<Config>& g_,              no_property&)        {          typedef typename Config::global_edgelist_selector EdgeListS;          BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));          typedef typename Config::graph_type graph_type;          graph_type& g = static_cast<graph_type&>(g_);          no_property* p = (no_property*)e.get_property();          typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g));          typename Config::OutEdgeList::iterator out_i = out_el.begin();          for (; out_i != out_el.end(); ++out_i)            if (&(*out_i).get_property() == p) {              out_el.erase(out_i);              break;            }          typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g));          typename Config::OutEdgeList::iterator in_i = in_el.begin();          for (; in_i != in_el.end(); ++in_i)            if (&(*in_i).get_property() == p) {              g.m_edges.erase((*in_i).get_iter());              in_el.erase(in_i);              return;            }        }      };      // O(E/V)      template <class Graph, class EdgeList, class Vertex>      inline void      remove_edge_and_property(Graph& g, EdgeList& el, Vertex v,                                boost::allow_parallel_edge_tag cat)      {        typedef typename Graph::global_edgelist_selector EdgeListS;        BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));        typedef typename EdgeList::value_type StoredEdge;        typename EdgeList::iterator i = el.begin(), end = el.end();        for (; i != end; ++i)          if ((*i).get_target() == v)            g.m_edges.erase((*i).get_iter());        detail::erase_from_incidence_list(el, v, cat);      }      // O(log(E/V))      template <class Graph, class EdgeList, class Vertex>      inline void      remove_edge_and_property(Graph& g, EdgeList& el, Vertex v,                                boost::disallow_parallel_edge_tag)      {        typedef typename Graph::global_edgelist_selector EdgeListS;        BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));        typedef typename EdgeList::value_type StoredEdge;        typename EdgeList::iterator i = el.find(StoredEdge(v)), end = el.end();        if (i != end) {          g.m_edges.erase((*i).get_iter());          el.erase(i);        }      }    } // namespace detail    template <class Vertex, class EdgeProperty>    struct list_edge // short name due to VC++ truncation and linker problems      : public boost::detail::edge_base<boost::undirected_tag, Vertex>    {      typedef EdgeProperty property_type;      typedef boost::detail::edge_base<boost::undirected_tag, Vertex> Base;      list_edge(Vertex u, Vertex v, const EdgeProperty& p = EdgeProperty())        : Base(u, v), m_property(p) { }      EdgeProperty& get_property() { return m_property; }      const EdgeProperty& get_property() const { return m_property; }      // the following methods should never be used, but are needed      // to make SGI MIPSpro C++ happy      list_edge() { }      bool operator==(const list_edge&) const { return false; }      bool operator<(const list_edge&) const { return false; }      EdgeProperty m_property;    };    template <class Config>    struct undirected_graph_helper {      typedef undir_adj_list_traversal_tag traversal_category;      // Placement of these overloaded remove_edge() functions      // inside the class avoids a VC++ bug.      // O(E/V)      inline void      remove_edge(typename Config::edge_descriptor e)      {        typedef typename Config::global_edgelist_selector EdgeListS;        BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));        typedef typename Config::OutEdgeList::value_type::property_type PType;        detail::remove_undirected_edge_dispatch<PType>::apply          (e, *this, *(PType*)e.get_property());      }      // O(E/V)      inline void      remove_edge(typename Config::out_edge_iterator iter)      {        this->remove_edge(*iter);      }    };    // Had to make these non-members to avoid accidental instantiation    // on SGI MIPSpro C++    template <class C>    inline typename C::InEdgeList&     in_edge_list(undirected_graph_helper<C>&,                  typename C::vertex_descriptor v)    {      typename C::stored_vertex* sv = (typename C::stored_vertex*)v;      return sv->m_out_edges;    }    template <class C>    inline const typename C::InEdgeList&     in_edge_list(const undirected_graph_helper<C>&,                 typename C::vertex_descriptor v) {      typename C::stored_vertex* sv = (typename C::stored_vertex*)v;      return sv->m_out_edges;    }    // O(E/V)    template <class EdgeOrIter, class Config>    inline void    remove_edge(EdgeOrIter e, undirected_graph_helper<Config>& g_)    {      typedef typename Config::global_edgelist_selector EdgeListS;      BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));      g_.remove_edge(e);    }    // O(E/V) or O(log(E/V))    template <class Config>    void    remove_edge(typename Config::vertex_descriptor u,                 typename Config::vertex_descriptor v,                 undirected_graph_helper<Config>& g_)    {      typedef typename Config::global_edgelist_selector EdgeListS;      BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));      typedef typename Config::graph_type graph_type;      graph_type& g = static_cast<graph_type&>(g_);      typedef typename Config::edge_parallel_category Cat;      detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat());      detail::erase_from_incidence_list(g.out_edge_list(v), u, Cat());    }      template <class Config, class Predicate>    void    remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred,                       undirected_graph_helper<Config>& g_)    {      typedef typename Config::global_edgelist_selector EdgeListS;      BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));              typedef typename Config::graph_type graph_type;      typedef typename Config::OutEdgeList::value_type::property_type PropT;      graph_type& g = static_cast<graph_type&>(g_);      typename Config::out_edge_iterator first, last;      tie(first, last) = out_edges(u, g);      typedef typename Config::edge_parallel_category Cat;      detail::undirected_remove_out_edge_if_dispatch<PropT>        (g, first, last, g.out_edge_list(u), pred, Cat());    }    template <class Config, class Predicate>    void    remove_in_edge_if(typename Config::vertex_descriptor u, Predicate pred,                      undirected_graph_helper<Config>& g_)    {      typedef typename Config::global_edgelist_selector EdgeListS;      BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));      remove_out_edge_if(u, pred, g_);    }    // O(E/V * E) or O(log(E/V) * E)    template <class Predicate, class Config>    void    remove_edge_if(Predicate pred, undirected_graph_helper<Config>& g_)    {      typedef typename Config::global_edgelist_selector EdgeListS;      BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));      typedef typename Config::graph_type graph_type;      graph_type& g = static_cast<graph_type&>(g_);      typename Config::edge_iterator ei, ei_end, next;      tie(ei, ei_end) = edges(g);      for (next = ei; ei != ei_end; ei = next) {        ++next;        if (pred(*ei))          remove_edge(*ei, g);      }    }    // O(1)    template <class Config>    inline std::pair<typename Config::edge_iterator,                      typename Config::edge_iterator>    edges(const undirected_graph_helper<Config>& g_)    {      typedef typename Config::graph_type graph_type;      typedef typename Config::edge_iterator edge_iterator;      const graph_type& cg = static_cast<const graph_type&>(g_);      graph_type& g = const_cast<graph_type&>(cg);      return std::make_pair( edge_iterator(g.m_edges.begin()),                             edge_iterator(g.m_edges.end()) );    }    // O(1)    template <class Config>    inline typename Config::edges_size_type    num_edges(const undirected_graph_helper<Config>& g_)     {      typedef typename Config::graph_type graph_type;      const graph_type& g = static_cast<const graph_type&>(g_);      return g.m_edges.size();    }    // O(E/V * E/V)    template <class Config>    inline void     clear_vertex(typename Config::vertex_descriptor u,                 undirected_graph_helper<Config>& g_)    {      typedef typename Config::global_edgelist_selector EdgeListS;      BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));      typedef typename Config::graph_type graph_type;      typedef typename Config::edge_parallel_category Cat;      graph_type& g = static_cast<graph_type&>(g_);      typename Config::OutEdgeList& el = g.out_edge_list(u);      typename Config::OutEdgeList::iterator         ei = el.begin(), ei_end = el.end();      for (; ei != ei_end; ++ei) {        detail::erase_from_incidence_list          (g.out_edge_list((*ei).get_target()), u, Cat());        g.m_edges.erase((*ei).get_iter());      }      g.out_edge_list(u).clear();    }    // O(1) for allow_parallel_edge_tag    // O(log(E/V)) for disallow_parallel_edge_tag    template <class Config>    inline std::pair<typename Config::edge_descriptor, bool>    add_edge(typename Config::vertex_descriptor u,              typename Config::vertex_descriptor v,              const typename Config::edge_property_type& p,             undirected_graph_helper<Config>& g_)    {      typedef typename Config::StoredEdge StoredEdge;      typedef typename Config::edge_descriptor edge_descriptor;      typedef typename Config::graph_type graph_type;      graph_type& g = static_cast<graph_type&>(g_);      bool inserted;      typename Config::EdgeContainer::value_type e(u, v, p);      typename Config::EdgeContainer::iterator p_iter         = graph_detail::push(g.m_edges, e).first;      typename Config::OutEdgeList::iterator i;      boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u),                                     StoredEdge(v, p_iter, &g.m_edges));      if (inserted) {        boost::graph_detail::push(g.out_edge_list(v), StoredEdge(u, p_iter, &g.m_edges));        return std::make_pair(edge_descriptor(u, v, &p_iter->get_property()),                              true);      } else {        g.m_edges.erase(p_iter);        return std::make_pair          (edge_descriptor(u, v, &i->get_iter()->get_property()), false);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -