gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
2 4 0
merge default
2 files changed with 91 insertions and 107 deletions:
↑ Collapse diff ↑
Ignore white space 768 line context
1 1
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
2 2

	
3 3
LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
4 4

	
5 5
SET(TESTS
6 6
  bfs_test
7
  circulation_test
7 8
  counter_test
8 9
  dfs_test
9 10
  digraph_test
10 11
  dijkstra_test
11 12
  dim_test
12 13
  error_test
14
  graph_adaptor_test
13 15
  graph_copy_test
14 16
  graph_test
15 17
  graph_utils_test
16 18
  hao_orlin_test
17 19
  heap_test
18 20
  kruskal_test
19 21
  maps_test
20 22
  max_matching_test
23
  path_test
24
  preflow_test
21 25
  random_test
22
  path_test
26
  suurballe_test
23 27
  time_measure_test
24 28
  unionfind_test)
25 29

	
26 30
FOREACH(TEST_NAME ${TESTS})
27 31
  ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
28 32
  TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
29 33
  ADD_TEST(${TEST_NAME} ${TEST_NAME})
30 34
ENDFOREACH(TEST_NAME)
Ignore white space 768 line context
1 1
EXTRA_DIST += \
2
	test/CMakeLists.txt \
3
        test/min_cost_flow_test.lgf \
4
        test/preflow_graph.lgf
2
	test/CMakeLists.txt
5 3

	
6 4
noinst_HEADERS += \
7 5
	test/graph_test.h \
8 6
        test/test_tools.h
9 7

	
10 8
check_PROGRAMS += \
11 9
	test/bfs_test \
12 10
        test/circulation_test \
13 11
        test/counter_test \
14 12
	test/dfs_test \
15 13
	test/digraph_test \
16 14
	test/dijkstra_test \
17 15
        test/dim_test \
18 16
	test/error_test \
19 17
	test/graph_adaptor_test \
20 18
	test/graph_copy_test \
21 19
	test/graph_test \
22 20
	test/graph_utils_test \
21
	test/hao_orlin_test \
23 22
	test/heap_test \
24 23
	test/kruskal_test \
25
	test/hao_orlin_test \
26 24
        test/maps_test \
27 25
	test/max_matching_test \
28
        test/random_test \
29 26
        test/path_test \
30 27
        test/preflow_test \
28
        test/random_test \
31 29
        test/suurballe_test \
32 30
        test/test_tools_fail \
33 31
        test/test_tools_pass \
34 32
        test/time_measure_test \
35 33
	test/unionfind_test
36 34

	
37 35
TESTS += $(check_PROGRAMS)
38 36
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
39 37

	
40 38
test_bfs_test_SOURCES = test/bfs_test.cc
41 39
test_circulation_test_SOURCES = test/circulation_test.cc
42 40
test_counter_test_SOURCES = test/counter_test.cc
43 41
test_dfs_test_SOURCES = test/dfs_test.cc
44 42
test_digraph_test_SOURCES = test/digraph_test.cc
45 43
test_dijkstra_test_SOURCES = test/dijkstra_test.cc
46 44
test_dim_test_SOURCES = test/dim_test.cc
47 45
test_error_test_SOURCES = test/error_test.cc
48 46
test_graph_adaptor_test_SOURCES = test/graph_adaptor_test.cc
49 47
test_graph_copy_test_SOURCES = test/graph_copy_test.cc
50 48
test_graph_test_SOURCES = test/graph_test.cc
51 49
test_graph_utils_test_SOURCES = test/graph_utils_test.cc
52 50
test_heap_test_SOURCES = test/heap_test.cc
53 51
test_kruskal_test_SOURCES = test/kruskal_test.cc
54 52
test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
55 53
test_maps_test_SOURCES = test/maps_test.cc
56 54
test_max_matching_test_SOURCES = test/max_matching_test.cc
57 55
test_path_test_SOURCES = test/path_test.cc
58 56
test_preflow_test_SOURCES = test/preflow_test.cc
59 57
test_suurballe_test_SOURCES = test/suurballe_test.cc
60 58
test_random_test_SOURCES = test/random_test.cc
61 59
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
62 60
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
63 61
test_time_measure_test_SOURCES = test/time_measure_test.cc
64 62
test_unionfind_test_SOURCES = test/unionfind_test.cc
Ignore white space 768 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19
#include <fstream>
20
#include <string>
19
#include <iostream>
21 20

	
22 21
#include "test_tools.h"
23 22
#include <lemon/smart_graph.h>
24 23
#include <lemon/preflow.h>
25 24
#include <lemon/concepts/digraph.h>
26 25
#include <lemon/concepts/maps.h>
27 26
#include <lemon/lgf_reader.h>
28 27
#include <lemon/elevator.h>
29 28

	
30 29
using namespace lemon;
31 30

	
31
char test_lgf[] =
32
  "@nodes\n"
33
  "label\n"
34
  "0\n"
35
  "1\n"
36
  "2\n"
37
  "3\n"
38
  "4\n"
39
  "5\n"
40
  "6\n"
41
  "7\n"
42
  "8\n"
43
  "9\n"
44
  "@arcs\n"
45
  "    label capacity\n"
46
  "0 1 0     20\n"
47
  "0 2 1     0\n"
48
  "1 1 2     3\n"
49
  "1 2 3     8\n"
50
  "1 3 4     8\n"
51
  "2 5 5     5\n"
52
  "3 2 6     5\n"
53
  "3 5 7     5\n"
54
  "3 6 8     5\n"
55
  "4 3 9     3\n"
56
  "5 7 10    3\n"
57
  "5 6 11    10\n"
58
  "5 8 12    10\n"
59
  "6 8 13    8\n"
60
  "8 9 14    20\n"
61
  "8 1 15    5\n"
62
  "9 5 16    5\n"
63
  "@attributes\n"
64
  "source 1\n"
65
  "target 8\n";
66

	
32 67
void checkPreflowCompile()
33 68
{
34 69
  typedef int VType;
35 70
  typedef concepts::Digraph Digraph;
36 71

	
37 72
  typedef Digraph::Node Node;
38 73
  typedef Digraph::Arc Arc;
39 74
  typedef concepts::ReadMap<Arc,VType> CapMap;
40 75
  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
41 76
  typedef concepts::WriteMap<Node,bool> CutMap;
42 77

	
43 78
  typedef Elevator<Digraph, Digraph::Node> Elev;
44 79
  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
45 80

	
46 81
  Digraph g;
47 82
  Node n;
48 83
  Arc e;
49 84
  CapMap cap;
50 85
  FlowMap flow;
51 86
  CutMap cut;
52 87

	
53 88
  Preflow<Digraph, CapMap>
54 89
    ::SetFlowMap<FlowMap>
55 90
    ::SetElevator<Elev>
56 91
    ::SetStandardElevator<LinkedElev>
57 92
    ::Create preflow_test(g,cap,n,n);
58 93

	
59 94
  preflow_test.capacityMap(cap);
60 95
  flow = preflow_test.flowMap();
61 96
  preflow_test.flowMap(flow);
62 97
  preflow_test.source(n);
63 98
  preflow_test.target(n);
64 99

	
65 100
  preflow_test.init();
66 101
  preflow_test.init(cap);
67 102
  preflow_test.startFirstPhase();
68 103
  preflow_test.startSecondPhase();
69 104
  preflow_test.run();
70 105
  preflow_test.runMinCut();
71 106

	
72 107
  preflow_test.flowValue();
73 108
  preflow_test.minCut(n);
74 109
  preflow_test.minCutMap(cut);
75 110
  preflow_test.flow(e);
76 111

	
77 112
}
78 113

	
79 114
int cutValue (const SmartDigraph& g,
80 115
              const SmartDigraph::NodeMap<bool>& cut,
81 116
              const SmartDigraph::ArcMap<int>& cap) {
82 117

	
83 118
  int c=0;
84 119
  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
85 120
    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
86 121
  }
87 122
  return c;
88 123
}
89 124

	
90 125
bool checkFlow(const SmartDigraph& g,
91 126
               const SmartDigraph::ArcMap<int>& flow,
92 127
               const SmartDigraph::ArcMap<int>& cap,
93 128
               SmartDigraph::Node s, SmartDigraph::Node t) {
94 129

	
95 130
  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
96 131
    if (flow[e] < 0 || flow[e] > cap[e]) return false;
97 132
  }
98 133

	
99 134
  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
100 135
    if (n == s || n == t) continue;
101 136
    int sum = 0;
102 137
    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
103 138
      sum += flow[e];
104 139
    }
105 140
    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
106 141
      sum -= flow[e];
107 142
    }
108 143
    if (sum != 0) return false;
109 144
  }
110 145
  return true;
111 146
}
112 147

	
113 148
int main() {
114 149

	
115 150
  typedef SmartDigraph Digraph;
116 151

	
117 152
  typedef Digraph::Node Node;
118 153
  typedef Digraph::NodeIt NodeIt;
119 154
  typedef Digraph::ArcIt ArcIt;
120 155
  typedef Digraph::ArcMap<int> CapMap;
121 156
  typedef Digraph::ArcMap<int> FlowMap;
122 157
  typedef Digraph::NodeMap<bool> CutMap;
123 158

	
124 159
  typedef Preflow<Digraph, CapMap> PType;
125 160

	
126
  std::string f_name;
127
  if( getenv("srcdir") )
128
    f_name = std::string(getenv("srcdir"));
129
  else f_name = ".";
130
  f_name += "/test/preflow_graph.lgf";
131

	
132
  std::ifstream file(f_name.c_str());
133

	
134
  check(file, "Input file '" << f_name << "' not found.");
135

	
136 161
  Digraph g;
137 162
  Node s, t;
138 163
  CapMap cap(g);
139
  DigraphReader<Digraph>(g,file).
164
  std::istringstream input(test_lgf);
165
  DigraphReader<Digraph>(g,input).
140 166
    arcMap("capacity", cap).
141 167
    node("source",s).
142 168
    node("target",t).
143 169
    run();
144 170

	
145 171
  PType preflow_test(g, cap, s, t);
146 172
  preflow_test.run();
147 173

	
148 174
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
149 175
        "The flow is not feasible.");
150 176

	
151 177
  CutMap min_cut(g);
152 178
  preflow_test.minCutMap(min_cut);
153 179
  int min_cut_value=cutValue(g,min_cut,cap);
154 180

	
155 181
  check(preflow_test.flowValue() == min_cut_value,
156 182
        "The max flow value is not equal to the three min cut values.");
157 183

	
158 184
  FlowMap flow(g);
159 185
  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
160 186

	
161 187
  int flow_value=preflow_test.flowValue();
162 188

	
163 189
  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
164 190
  preflow_test.init(flow);
165 191
  preflow_test.startFirstPhase();
166 192

	
167 193
  CutMap min_cut1(g);
168 194
  preflow_test.minCutMap(min_cut1);
169 195
  min_cut_value=cutValue(g,min_cut1,cap);
170 196

	
171 197
  check(preflow_test.flowValue() == min_cut_value &&
172 198
        min_cut_value == 2*flow_value,
173 199
        "The max flow value or the min cut value is wrong.");
174 200

	
175 201
  preflow_test.startSecondPhase();
176 202

	
177 203
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
178 204
        "The flow is not feasible.");
179 205

	
180 206
  CutMap min_cut2(g);
181 207
  preflow_test.minCutMap(min_cut2);
182 208
  min_cut_value=cutValue(g,min_cut2,cap);
183 209

	
184 210
  check(preflow_test.flowValue() == min_cut_value &&
185 211
        min_cut_value == 2*flow_value,
186 212
        "The max flow value or the three min cut values were not doubled");
187 213

	
188 214

	
189 215
  preflow_test.flowMap(flow);
190 216

	
191 217
  NodeIt tmp1(g,s);
192 218
  ++tmp1;
193 219
  if ( tmp1 != INVALID ) s=tmp1;
194 220

	
195 221
  NodeIt tmp2(g,t);
196 222
  ++tmp2;
197 223
  if ( tmp2 != INVALID ) t=tmp2;
198 224

	
199 225
  preflow_test.source(s);
200 226
  preflow_test.target(t);
201 227

	
202 228
  preflow_test.run();
203 229

	
204 230
  CutMap min_cut3(g);
205 231
  preflow_test.minCutMap(min_cut3);
206 232
  min_cut_value=cutValue(g,min_cut3,cap);
207 233

	
208 234

	
209 235
  check(preflow_test.flowValue() == min_cut_value,
210 236
        "The max flow value or the three min cut values are incorrect.");
211 237

	
212 238
  return 0;
213 239
}
Ignore white space 768 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <iostream>
20
#include <fstream>
21 20

	
22 21
#include <lemon/list_graph.h>
23 22
#include <lemon/lgf_reader.h>
24 23
#include <lemon/path.h>
25 24
#include <lemon/suurballe.h>
26 25

	
27 26
#include "test_tools.h"
28 27

	
29 28
using namespace lemon;
30 29

	
30
char test_lgf[] =
31
  "@nodes\n"
32
  "label supply1 supply2 supply3\n"
33
  "1     0        20      27\n"
34
  "2     0       -4        0\n"
35
  "3     0        0        0\n"
36
  "4     0        0        0\n"
37
  "5     0        9        0\n"
38
  "6     0       -6        0\n"
39
  "7     0        0        0\n"
40
  "8     0        0        0\n"
41
  "9     0        3        0\n"
42
  "10    0       -2        0\n"
43
  "11    0        0        0\n"
44
  "12    0       -20     -27\n"
45
  "@arcs\n"
46
  "      cost capacity lower1 lower2\n"
47
  " 1  2  70  11       0      8\n"
48
  " 1  3 150   3       0      1\n"
49
  " 1  4  80  15       0      2\n"
50
  " 2  8  80  12       0      0\n"
51
  " 3  5 140   5       0      3\n"
52
  " 4  6  60  10       0      1\n"
53
  " 4  7  80   2       0      0\n"
54
  " 4  8 110   3       0      0\n"
55
  " 5  7  60  14       0      0\n"
56
  " 5 11 120  12       0      0\n"
57
  " 6  3   0   3       0      0\n"
58
  " 6  9 140   4       0      0\n"
59
  " 6 10  90   8       0      0\n"
60
  " 7  1  30   5       0      0\n"
61
  " 8 12  60  16       0      4\n"
62
  " 9 12  50   6       0      0\n"
63
  "10 12  70  13       0      5\n"
64
  "10  2 100   7       0      0\n"
65
  "10  7  60  10       0      0\n"
66
  "11 10  20  14       0      6\n"
67
  "12 11  30  10       0      0\n"
68
  "@attributes\n"
69
  "source  1\n"
70
  "target 12\n"
71
  "@end\n";
72

	
31 73
// Check the feasibility of the flow
32 74
template <typename Digraph, typename FlowMap>
33 75
bool checkFlow( const Digraph& gr, const FlowMap& flow, 
34 76
                typename Digraph::Node s, typename Digraph::Node t,
35 77
                int value )
36 78
{
37 79
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
38 80
  for (ArcIt e(gr); e != INVALID; ++e)
39 81
    if (!(flow[e] == 0 || flow[e] == 1)) return false;
40 82

	
41 83
  for (NodeIt n(gr); n != INVALID; ++n) {
42 84
    int sum = 0;
43 85
    for (OutArcIt e(gr, n); e != INVALID; ++e)
44 86
      sum += flow[e];
45 87
    for (InArcIt e(gr, n); e != INVALID; ++e)
46 88
      sum -= flow[e];
47 89
    if (n == s && sum != value) return false;
48 90
    if (n == t && sum != -value) return false;
49 91
    if (n != s && n != t && sum != 0) return false;
50 92
  }
51 93

	
52 94
  return true;
53 95
}
54 96

	
55 97
// Check the optimalitiy of the flow
56 98
template < typename Digraph, typename CostMap, 
57 99
           typename FlowMap, typename PotentialMap >
58 100
bool checkOptimality( const Digraph& gr, const CostMap& cost,
59 101
                      const FlowMap& flow, const PotentialMap& pi )
60 102
{
61 103
  // Check the "Complementary Slackness" optimality condition
62 104
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
63 105
  bool opt = true;
64 106
  for (ArcIt e(gr); e != INVALID; ++e) {
65 107
    typename CostMap::Value red_cost =
66 108
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
67 109
    opt = (flow[e] == 0 && red_cost >= 0) ||
68 110
          (flow[e] == 1 && red_cost <= 0);
69 111
    if (!opt) break;
70 112
  }
71 113
  return opt;
72 114
}
73 115

	
74 116
// Check a path
75 117
template <typename Digraph, typename Path>
76 118
bool checkPath( const Digraph& gr, const Path& path,
77 119
                typename Digraph::Node s, typename Digraph::Node t)
78 120
{
79 121
  // Check the "Complementary Slackness" optimality condition
80 122
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
81 123
  Node n = s;
82 124
  for (int i = 0; i < path.length(); ++i) {
83 125
    if (gr.source(path.nth(i)) != n) return false;
84 126
    n = gr.target(path.nth(i));
85 127
  }
86 128
  return n == t;
87 129
}
88 130

	
89 131

	
90 132
int main()
91 133
{
92 134
  DIGRAPH_TYPEDEFS(ListDigraph);
93 135

	
94 136
  // Read the test digraph
95 137
  ListDigraph digraph;
96 138
  ListDigraph::ArcMap<int> length(digraph);
97 139
  Node source, target;
98 140

	
99
  std::string fname;
100
  if(getenv("srcdir"))
101
    fname = std::string(getenv("srcdir"));
102
  else fname = ".";
103
  fname += "/test/min_cost_flow_test.lgf";
104

	
105
  std::ifstream input(fname.c_str());
106
  check(input, "Input file '" << fname << "' not found");
141
  std::istringstream input(test_lgf);
107 142
  DigraphReader<ListDigraph>(digraph, input).
108 143
    arcMap("cost", length).
109 144
    node("source", source).
110 145
    node("target", target).
111 146
    run();
112
  input.close();
113 147
  
114 148
  // Find 2 paths
115 149
  {
116 150
    Suurballe<ListDigraph> suurballe(digraph, length, source, target);
117 151
    check(suurballe.run(2) == 2, "Wrong number of paths");
118 152
    check(checkFlow(digraph, suurballe.flowMap(), source, target, 2),
119 153
          "The flow is not feasible");
120 154
    check(suurballe.totalLength() == 510, "The flow is not optimal");
121 155
    check(checkOptimality(digraph, length, suurballe.flowMap(), 
122 156
                          suurballe.potentialMap()),
123 157
          "Wrong potentials");
124 158
    for (int i = 0; i < suurballe.pathNum(); ++i)
125 159
      check(checkPath(digraph, suurballe.path(i), source, target),
126 160
            "Wrong path");
127 161
  }
128 162

	
129 163
  // Find 3 paths
130 164
  {
131 165
    Suurballe<ListDigraph> suurballe(digraph, length, source, target);
132 166
    check(suurballe.run(3) == 3, "Wrong number of paths");
133 167
    check(checkFlow(digraph, suurballe.flowMap(), source, target, 3),
134 168
          "The flow is not feasible");
135 169
    check(suurballe.totalLength() == 1040, "The flow is not optimal");
136 170
    check(checkOptimality(digraph, length, suurballe.flowMap(), 
137 171
                          suurballe.potentialMap()),
138 172
          "Wrong potentials");
139 173
    for (int i = 0; i < suurballe.pathNum(); ++i)
140 174
      check(checkPath(digraph, suurballe.path(i), source, target),
141 175
            "Wrong path");
142 176
  }
143 177

	
144 178
  // Find 5 paths (only 3 can be found)
145 179
  {
146 180
    Suurballe<ListDigraph> suurballe(digraph, length, source, target);
147 181
    check(suurballe.run(5) == 3, "Wrong number of paths");
148 182
    check(checkFlow(digraph, suurballe.flowMap(), source, target, 3),
149 183
          "The flow is not feasible");
150 184
    check(suurballe.totalLength() == 1040, "The flow is not optimal");
151 185
    check(checkOptimality(digraph, length, suurballe.flowMap(), 
152 186
                          suurballe.potentialMap()),
153 187
          "Wrong potentials");
154 188
    for (int i = 0; i < suurballe.pathNum(); ++i)
155 189
      check(checkPath(digraph, suurballe.path(i), source, target),
156 190
            "Wrong path");
157 191
  }
158 192

	
159 193
  return 0;
160 194
}
Ignore white space 768 line context
1
@nodes
2
label	supply1	supply2	supply3
3
1	0	20	27	
4
2	0	-4	0		
5
3	0	0	0	
6
4	0	0	0	
7
5	0	9	0	
8
6	0	-6	0	
9
7	0	0	0	
10
8	0	0	0	
11
9	0	3	0	
12
10	0	-2	0	
13
11	0	0	0		
14
12	0	-20	-27	
15
               
16
@arcs
17
		cost	capacity	lower1	lower2
18
1	2	70	11		0	8
19
1	3	150	3		0	1
20
1	4	80	15		0	2
21
2	8	80	12		0	0
22
3	5	140	5		0	3
23
4	6	60	10		0	1
24
4	7	80	2		0	0
25
4	8	110	3		0	0
26
5	7	60	14		0	0
27
5	11	120	12		0	0
28
6	3	0	3		0	0
29
6	9	140	4		0	0
30
6	10	90	8		0	0
31
7	1	30	5		0	0
32
8	12	60	16		0	4
33
9	12	50	6		0	0
34
10	12	70	13		0	5
35
10	2	100	7		0	0
36
10	7	60	10		0	0
37
11	10	20	14		0	6
38
12	11	30	10		0	0
39

	
40
@attributes
41
source	1
42
target	12
43

	
44
@end
Ignore white space 768 line context
1
@nodes
2
label
3
0
4
1
5
2
6
3
7
4
8
5
9
6
10
7
11
8
12
9
13
@arcs
14
		label	capacity
15
0	1	0	20
16
0	2	1	0
17
1	1	2	3
18
1	2	3	8
19
1	3	4	8
20
2	5	5	5
21
3	2	6	5
22
3	5	7	5
23
3	6	8	5
24
4	3	9	3
25
5	7	10	3
26
5	6	11	10
27
5	8	12	10
28
6	8	13	8
29
8	9	14	20
30
8	1	15	5
31
9	5	16	5
32
@attributes
33
source 1
34
target 8
0 comments (0 inline)