read_write_dimacs-eg.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Copyright (c) 2006, Stephan Diederich
  2. //
  3. // This code may be used under either of the following two licences:
  4. //
  5. // Permission is hereby granted, free of charge, to any person
  6. // obtaining a copy of this software and associated documentation
  7. // files (the "Software"), to deal in the Software without
  8. // restriction, including without limitation the rights to use,
  9. // copy, modify, merge, publish, distribute, sublicense, and/or
  10. // sell copies of the Software, and to permit persons to whom the
  11. // Software is furnished to do so, subject to the following
  12. // conditions:
  13. //
  14. // The above copyright notice and this permission notice shall be
  15. // included in all copies or substantial portions of the Software.
  16. //
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  19. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  21. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  22. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  23. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  24. // OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE.
  25. //
  26. // Or:
  27. //
  28. // Distributed under the Boost Software License, Version 1.0.
  29. // (See accompanying file LICENSE_1_0.txt or copy at
  30. // http://www.boost.org/LICENSE_1_0.txt)
  31. #ifdef _MSC_VER
  32. #define _CRT_SECURE_NO_WARNINGS
  33. #endif
  34. #include <boost/config.hpp>
  35. #include <iostream>
  36. #include <string>
  37. #include <boost/graph/adjacency_list.hpp>
  38. #include <boost/graph/read_dimacs.hpp>
  39. #include <boost/graph/write_dimacs.hpp>
  40. /*************************************
  41. *
  42. * example which reads in a max-flow problem from std::cin, augments all paths from
  43. * source->NODE->sink and writes the graph back to std::cout
  44. *
  45. **************************************/
  46. template <typename EdgeCapacityMap>
  47. struct zero_edge_capacity{
  48. zero_edge_capacity() { }
  49. zero_edge_capacity(EdgeCapacityMap cap_map):m_cap_map(cap_map){};
  50. template <typename Edge>
  51. bool operator() (const Edge& e) const {
  52. return get(m_cap_map, e) == 0 ;
  53. }
  54. EdgeCapacityMap m_cap_map;
  55. };
  56. int main()
  57. {
  58. using namespace boost;
  59. typedef adjacency_list_traits < vecS, vecS, directedS > Traits;
  60. typedef adjacency_list < vecS, vecS, directedS,
  61. no_property,
  62. property < edge_capacity_t, long,
  63. property < edge_reverse_t, Traits::edge_descriptor > > > Graph;
  64. typedef graph_traits<Graph>::out_edge_iterator out_edge_iterator;
  65. typedef graph_traits<Graph>::edge_descriptor edge_descriptor;
  66. typedef graph_traits<Graph>::vertex_descriptor vertex_descriptor;
  67. Graph g;
  68. typedef property_map < Graph, edge_capacity_t >::type tCapMap;
  69. typedef tCapMap::value_type tCapMapValue;
  70. typedef property_map < Graph, edge_reverse_t >::type tRevEdgeMap;
  71. tCapMap capacity = get(edge_capacity, g);
  72. tRevEdgeMap rev = get(edge_reverse, g);
  73. vertex_descriptor s, t;
  74. /*reading the graph from stdin*/
  75. read_dimacs_max_flow(g, capacity, rev, s, t, std::cin);
  76. /*process graph*/
  77. tCapMapValue augmented_flow = 0;
  78. //we take the source node and check for each outgoing edge e which has a target(p) if we can augment that path
  79. out_edge_iterator oei,oe_end;
  80. for(boost::tie(oei, oe_end) = out_edges(s, g); oei != oe_end; ++oei){
  81. edge_descriptor from_source = *oei;
  82. vertex_descriptor v = target(from_source, g);
  83. edge_descriptor to_sink;
  84. bool is_there;
  85. boost::tie(to_sink, is_there) = edge(v, t, g);
  86. if( is_there ){
  87. if( get(capacity, to_sink) > get(capacity, from_source) ){
  88. tCapMapValue to_augment = get(capacity, from_source);
  89. capacity[from_source] = 0;
  90. capacity[to_sink] -= to_augment;
  91. augmented_flow += to_augment;
  92. }else{
  93. tCapMapValue to_augment = get(capacity, to_sink);
  94. capacity[to_sink] = 0;
  95. capacity[from_source] -= to_augment;
  96. augmented_flow += to_augment;
  97. }
  98. }
  99. }
  100. //remove edges with zero capacity (most of them are the reverse edges)
  101. zero_edge_capacity<tCapMap> filter(capacity);
  102. remove_edge_if(filter, g);
  103. /*write the graph back to stdout */
  104. write_dimacs_max_flow(g, capacity, identity_property_map(),s, t, std::cout);
  105. //print flow we augmented to std::cerr
  106. std::cerr << "removed " << augmented_flow << " from SOURCE->NODE->SINK connects" <<std::endl;
  107. return 0;
  108. }