Advertisement
homer512

graph

May 24th, 2015
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.55 KB | None | 0 0
  1. #include <set>
  2. /* using std::set */
  3. #include <map>
  4. /* using std::map */
  5. #include <array>
  6. /* using std::array */
  7. #include <memory>
  8. /* using std::shared_ptr, std::make_shared, std::enable_shared_from_this,
  9.  * std::weak_ptr */
  10. #include <utility>
  11. /* using std::move, std::pair, std::make_pair */
  12. #include <cassert>
  13. /* using assert */
  14. #include <iostream>
  15. /* using std::cout */
  16.  
  17.  
  18. namespace graph {
  19.  
  20.   class vertex;
  21.  
  22.   struct vertexcmp
  23.   {
  24.     bool operator()(const std::shared_ptr<vertex>& first,
  25.             const std::shared_ptr<vertex>& second) const noexcept;
  26.     bool operator()(const std::weak_ptr<vertex>& first,
  27.             const std::weak_ptr<vertex>& second) const noexcept
  28.     {
  29.       return (*this)(first.lock(), second.lock());
  30.     }
  31.   };
  32.  
  33.   using vertexset = std::set<std::shared_ptr<vertex>, vertexcmp>;
  34.   using backrefset = std::set<std::weak_ptr<vertex>, vertexcmp>;
  35.  
  36.   struct vertex: std::enable_shared_from_this<vertex>
  37.   {
  38.     vertexset children;
  39.     backrefset parents;
  40.     const int id;
  41.     vertex(int id) noexcept
  42.       : id(id)
  43.     {}
  44.     vertex(const vertex&) = delete;
  45.     vertex(vertex&&) = default;
  46.     bool add_child(const std::shared_ptr<vertex>& child)
  47.     {
  48.       assert(child);
  49.       if(! children.insert(child).second)
  50.     return false; /* already a child */
  51.       std::weak_ptr<vertex> self(this->shared_from_this());
  52.       bool newparent = child->parents.insert(std::move(self)).second;
  53.       assert(newparent);
  54.       return true;
  55.     }
  56.     bool remove_child(const std::shared_ptr<vertex>& child) noexcept
  57.     {
  58.       assert(child);
  59.       if(! children.erase(child))
  60.     return false;
  61.       std::weak_ptr<vertex> self(this->shared_from_this());
  62.       bool wasparent = child->parents.erase(std::move(self));
  63.       assert(wasparent);
  64.       return true;
  65.     }
  66.   };
  67.  
  68.   bool vertexcmp::operator()(const std::shared_ptr<vertex>& first,
  69.                  const std::shared_ptr<vertex>& second) const noexcept
  70.   {
  71.     assert(first && second);
  72.     return first->id < second->id;
  73.   }
  74.  
  75.   using edge = std::pair<int, int>;
  76.   using edgeset = std::set<edge>;
  77.  
  78.   void walk_graph(const std::shared_ptr<vertex>& node, edgeset& walked) noexcept
  79.   {
  80.     assert(node);
  81.     const vertexset& children = node->children;
  82.     int id = node->id;
  83.     for(const std::shared_ptr<vertex>& child: children) {
  84.       assert(child);
  85.       int childid = child->id;
  86.       bool notvisited = walked.insert(std::make_pair(id, childid)).second;
  87.       if(notvisited) {
  88.     std::cout << id << " -> " << childid << "\n";
  89.     walk_graph(child, walked);
  90.       }
  91.     }
  92.   }
  93.  
  94.   using vertexmap = std::map<int, std::shared_ptr<vertex> >;
  95.  
  96.   struct graphset
  97.   {
  98.     vertexmap vertexes;
  99.     std::shared_ptr<vertex>& operator[](int id)
  100.     {
  101.       std::shared_ptr<vertex>& node = vertexes[id];
  102.       if(node)
  103.     assert(node->id == id);
  104.       else
  105.     node = std::make_shared<vertex>(id);
  106.       return node;
  107.     }
  108.     bool add_edge(int from, int to)
  109.     {
  110.       std::shared_ptr<vertex>& parent = (*this)[from];
  111.       std::shared_ptr<vertex>& child = (*this)[to];
  112.       return parent->add_child(child);
  113.     }
  114.   };
  115.  
  116.   template<std::size_t n>
  117.   using edge_array = std::array<edge, n>;
  118. }
  119.  
  120. int main()
  121. {
  122.   graph::graphset testgraph;
  123.   static constexpr graph::edge_array<6> edges {
  124.     graph::edge{0, 1},
  125.     graph::edge{0, 4},
  126.     graph::edge{1, 2},
  127.     graph::edge{1, 3},
  128.     graph::edge{1, 4},
  129.     graph::edge{2, 3},
  130.   };
  131.   for(const graph::edge& e: edges)
  132.     testgraph.add_edge(e.first, e.second);
  133.   graph::edgeset walked;
  134.   graph::walk_graph(testgraph[0], walked);
  135. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement