1 //Robado de shygypsy.com/tools/mcmf4.cpp
4 * ///////////////////////
5 * // MIN COST MAX FLOW //
6 * ///////////////////////
8 * Authors: Frank Chu, Igor Naverniouk
11 /*********************
12 * Min cost max flow * (Edmonds-Karp relabelling + fast heap Dijkstra)
14 * Takes a directed graph where each edge has a capacity ('cap') and a
15 * cost per unit of flow ('cost') and returns a maximum flow network
16 * of minimal cost ('fcost') from s to t. USE mcmf3.cpp FOR DENSE GRAPHS!
19 * - cap (global): adjacency matrix where cap[u][v] is the capacity
20 * of the edge u->v. cap[u][v] is 0 for non-existent edges.
21 * - cost (global): a matrix where cost[u][v] is the cost per unit
22 * of flow along the edge u->v. If cap[u][v] == 0, cost[u][v] is
23 * ignored. ALL COSTS MUST BE NON-NEGATIVE!
24 * - n: the number of vertices ([0, n-1] are considered as vertices).
29 * - the total cost through 'fcost'
30 * - fnet contains the flow network. Careful: both fnet[u][v] and
31 * fnet[v][u] could be positive. Take the difference.
33 * - Worst case: O(m*log(m)*flow <? n*m*log(m)*fcost)
35 * - Valladolid 10594: Data Flow
37 * Edmonds, J., Karp, R. "Theoretical Improvements in Algorithmic
38 * Efficieincy for Network Flow Problems".
39 * This is a slight improvement of Frank Chu's implementation.
45 // the maximum number of vertices + 1
48 // adjacency matrix (fill this up)
51 // cost per unit of flow matrix (fill this up)
54 // flow network and adjacency list
55 int fnet
[NN
][NN
], adj
[NN
][NN
], deg
[NN
];
57 // Dijkstra's predecessor, depth and priority queue
58 int par
[NN
], d
[NN
], q
[NN
], inq
[NN
], qs
;
63 #define CLR(a, x) memset( a, x, sizeof( a ) )
64 #define Inf (INT_MAX/2)
66 t = q[i]; q[i] = q[j]; q[j] = t; \
67 t = inq[q[i]]; inq[q[i]] = inq[q[j]]; inq[q[j]] = t; }
69 // Dijkstra's using non-negative edge weights (cost + potential)
70 #define Pot(u,v) (d[u] + pi[u] - pi[v])
71 bool dijkstra( int n
, int s
, int t
)
76 //for( int i = 0; i < n; i++ ) d[i] = Inf, par[i] = -1;
83 // get the minimum from q and bubble down
84 int u
= q
[0]; inq
[u
] = -1;
86 if( qs
) inq
[q
[0]] = 0;
87 for( int i
= 0, j
= 2*i
+ 1, t
; j
< qs
; i
= j
, j
= 2*i
+ 1 )
89 if( j
+ 1 < qs
&& d
[q
[j
+ 1]] < d
[q
[j
]] ) j
++;
90 if( d
[q
[j
]] >= d
[q
[i
]] ) break;
94 // relax edge (u,i) or (i,u) for all i;
95 for( int k
= 0, v
= adj
[u
][k
]; k
< deg
[u
]; v
= adj
[u
][++k
] )
97 // try undoing edge v->u
98 if( fnet
[v
][u
] && d
[v
] > Pot(u
,v
) - cost
[v
][u
] )
99 d
[v
] = Pot(u
,v
) - cost
[v
][par
[v
] = u
];
101 // try using edge u->v
102 if( fnet
[u
][v
] < cap
[u
][v
] && d
[v
] > Pot(u
,v
) + cost
[u
][v
] )
103 d
[v
] = Pot(u
,v
) + cost
[par
[v
] = u
][v
];
107 // bubble up or decrease key
108 if( inq
[v
] < 0 ) { inq
[q
[qs
] = v
] = qs
; qs
++; }
109 for( int i
= inq
[v
], j
= ( i
- 1 )/2, t
;
110 d
[q
[i
]] < d
[q
[j
]]; i
= j
, j
= ( i
- 1 )/2 )
116 for( int i
= 0; i
< n
; i
++ ) if( pi
[i
] < Inf
) pi
[i
] += d
[i
];
122 int mcmf4( int n
, int s
, int t
, int &fcost
)
124 // build the adjacency list
126 for( int i
= 0; i
< n
; i
++ )
127 for( int j
= 0; j
< n
; j
++ )
128 if( cap
[i
][j
] || cap
[j
][i
] ) adj
[i
][deg
[i
]++] = j
;
132 int flow
= fcost
= 0;
134 // repeatedly, find a cheapest path from s to t
135 while( dijkstra( n
, s
, t
) )
137 // get the bottleneck capacity
139 for( int v
= t
, u
= par
[v
]; v
!= s
; u
= par
[v
= u
] )
140 bot
<?= fnet
[v
][u
] ? fnet
[v
][u
] : ( cap
[u
][v
] - fnet
[u
][v
] );
142 // update the flow network
143 for( int v
= t
, u
= par
[v
]; v
!= s
; u
= par
[v
= u
] )
144 if( fnet
[v
][u
] ) { fnet
[v
][u
] -= bot
; fcost
-= bot
* cost
[v
][u
]; }
145 else { fnet
[u
][v
] += bot
; fcost
+= bot
* cost
[u
][v
]; }
153 //----------------- EXAMPLE USAGE -----------------
161 // while ( cin >> numV && numV ) {
163 memset( cap
, 0, sizeof( cap
) );
170 // fill up cap with existing capacities.
171 // if the edge u->v has capacity 6, set cap[u][v] = 6.
172 // for each cap[u][v] > 0, set cost[u][v] to the
173 // cost per unit of flow along the edge i->v
174 for (int i
=0; i
<m
; i
++) {
175 cin
>> a
>> b
>> cp
>> c
;
176 cost
[a
][b
] = c
; // cost[b][a] = c;
177 cap
[a
][b
] = cp
; // cap[b][a] = cp;
181 int flow
= mcmf3( numV
, s
, t
, fcost
);
182 cout
<< "flow: " << flow
<< endl
;
183 cout
<< "cost: " << fcost
<< endl
;