min_cost_max_flow_utils.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //=======================================================================
  2. // Copyright 2013 University of Warsaw.
  3. // Authors: Piotr Wygocki
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. #ifndef SAMPLE_GRAPH_UNDIRECTED_HPP
  10. #define SAMPLE_GRAPH_UNDIRECTED_HPP
  11. #include <iostream>
  12. #include <cstdlib>
  13. #include <boost/graph/adjacency_list.hpp>
  14. namespace boost {
  15. struct SampleGraph {
  16. typedef adjacency_list_traits < vecS, vecS, directedS > Traits;
  17. typedef adjacency_list < vecS, vecS, directedS, no_property,
  18. property < edge_capacity_t, long,
  19. property < edge_residual_capacity_t, long,
  20. property < edge_reverse_t, Traits::edge_descriptor,
  21. property <edge_weight_t, long>
  22. >
  23. >
  24. > > Graph;
  25. typedef property_map < Graph, edge_capacity_t >::type Capacity;
  26. typedef property_map < Graph, edge_residual_capacity_t >::type ResidualCapacity;
  27. typedef property_map < Graph, edge_weight_t >::type Weight;
  28. typedef property_map < Graph, edge_reverse_t>::type Reversed;
  29. typedef boost::graph_traits<Graph>::vertices_size_type size_type;
  30. typedef Traits::vertex_descriptor vertex_descriptor;
  31. template <class Graph, class Weight, class Capacity, class Reversed, class ResidualCapacity>
  32. class EdgeAdder {
  33. public:
  34. EdgeAdder(Graph& g, Weight& w, Capacity& c, Reversed& rev
  35. , ResidualCapacity&) : m_g(g), m_w(w), m_cap(c), m_rev(rev) {}
  36. void addEdge(vertex_descriptor v, vertex_descriptor w, long weight, long capacity) {
  37. Traits::edge_descriptor e,f;
  38. e = add(v, w, weight, capacity);
  39. f = add(w, v, -weight, 0);
  40. m_rev[e] = f;
  41. m_rev[f] = e;
  42. }
  43. private:
  44. Traits::edge_descriptor add(vertex_descriptor v, vertex_descriptor w
  45. , long weight, long capacity)
  46. {
  47. bool b;
  48. Traits::edge_descriptor e;
  49. boost::tie(e, b) = add_edge(vertex(v, m_g), vertex(w, m_g), m_g);
  50. if (!b) {
  51. std::cerr << "Edge between " << v << " and " << w << " already exists." << std::endl;
  52. std::abort();
  53. }
  54. m_cap[e] = capacity;
  55. m_w[e] = weight;
  56. return e;
  57. }
  58. Graph & m_g;
  59. Weight & m_w;
  60. Capacity & m_cap;
  61. Reversed & m_rev;
  62. };
  63. static void getSampleGraph(Graph &g, vertex_descriptor & s, vertex_descriptor & t) {
  64. Capacity capacity = get(edge_capacity, g);
  65. Reversed rev = get(edge_reverse, g);
  66. ResidualCapacity residual_capacity = get(edge_residual_capacity, g);
  67. Weight weight = get(edge_weight, g);
  68. getSampleGraph(g,s,t,capacity,residual_capacity,weight,rev);
  69. }
  70. template <class Graph, class Weight, class Capacity, class Reversed, class ResidualCapacity>
  71. static void
  72. getSampleGraph(Graph &g, vertex_descriptor & s, vertex_descriptor & t,
  73. Capacity capacity, ResidualCapacity residual_capacity, Weight weight, Reversed rev) {
  74. size_type N(6);
  75. for(size_type i = 0; i < N; ++i){
  76. add_vertex(g);
  77. }
  78. s = 0;
  79. t = 5;
  80. EdgeAdder<Graph, Weight, Capacity, Reversed, ResidualCapacity> ea(g, weight, capacity, rev, residual_capacity);
  81. ea.addEdge(0, 1, 4 ,2);
  82. ea.addEdge(0, 2, 2 ,2);
  83. ea.addEdge(1, 3, 2 ,2);
  84. ea.addEdge(1, 4, 1 ,1);
  85. ea.addEdge(2, 3, 1 ,1);
  86. ea.addEdge(2, 4, 1 ,1);
  87. ea.addEdge(3, 5, 4 ,20);
  88. ea.addEdge(4, 5, 2 ,20);
  89. }
  90. static void getSampleGraph2(Graph &g, vertex_descriptor & s, vertex_descriptor & t) {
  91. const boost::graph_traits<Graph>::vertices_size_type N(5);
  92. typedef property_map < Graph, edge_reverse_t >::type Reversed;
  93. for(size_type i = 0; i < N; ++i){
  94. add_vertex(g);
  95. }
  96. Capacity capacity = get(edge_capacity, g);
  97. Reversed rev = get(edge_reverse, g);
  98. ResidualCapacity residual_capacity = get(edge_residual_capacity, g);
  99. Weight weight = get(edge_weight, g);
  100. s = 0;
  101. t = 4;
  102. EdgeAdder<Graph, Weight, Capacity, Reversed, ResidualCapacity> ea(g, weight, capacity, rev, residual_capacity);
  103. ea.addEdge(0, 1, 4 ,2);
  104. ea.addEdge(0, 2, 2 ,2);
  105. ea.addEdge(1, 2, 2 ,2);
  106. ea.addEdge(2, 3, 1 ,1);
  107. ea.addEdge(2, 4, 1 ,1);
  108. ea.addEdge(3, 4, 1 ,1);
  109. ea.addEdge(1, 0, 2 ,2);
  110. ea.addEdge(2, 0, 1 ,1);
  111. ea.addEdge(2, 1, 5 ,2);
  112. ea.addEdge(3, 2, 1 ,1);
  113. ea.addEdge(4, 2, 2 ,2);
  114. ea.addEdge(4, 3, 1 ,3);
  115. }
  116. };
  117. } //boost
  118. #endif /* SAMPLE_GRAPH_UNDIRECTED_HPP */