Acdream 1171 Matrix sum upstream and downstream billing Flow
Question link: Click the open link
Matrix sumTime Limit: 8000/4000 MS (Java/Others) Memory Limit: 128000/64000 KB (Java/Others) SubmitStatisticNext ProblemProblem Descriptionsweet and zero are playing Matrix games, sweet draws an N * M matrix. Each lattice in the matrix has an integer. Zero gives N number Ki, and M number Kj. zero requires sweet to select some numbers, satisfying at least the number of Ki selected from line I, and at least the number of Kj selected in column j. The sum of these values is the number of sweets sweet will pay zero. Sweet wants to know how many sweets he wants to give zero. Can you help him make an optimal strategy? Input
T (T <= 40) indicates the total number of data records, followed by T groups of data.
Data in each group:
N, M (1 <= N, M <= 50)
Next N rows, the number of M in each row (the range is an integer between 0 and)
The next row contains N numbers of Ki, indicating that at least the Ki elements (0 <= Ki <= M) are selected for row I)
The last row has M quantity Kj, indicating that at least Kj elements (0 <= Kj <= N) are selected in column j)
Output each group of data outputs a row. The minimum number of Sweets that sweet will pay to zero is the Sample Input.
14 41 1 1 11 10 10 101 10 10 101 10 10 101 1 1 11 1 1 1
Sample Output
6
Use n rows as the left endpoint m as the right endpoint to create a two-part Graph
The traffic from n points to the source point is inf, and the fee is 0.
The traffic from m points to the settlement point is inf, and the fee is 0.
The fee for connecting n and m points is mp [I] [j], and the traffic is 1.
--------------------------- The preceding figure is a normal graph -----------------------
To achieve a lower bound Effect
Add a cost-inf edge and the traffic is ki edge to the vertex corresponding to the lower bound. This forces the expense stream to run the edge where all fees are-inf first.
This means that the edge of the lower bound is full first.
When the fee is greater than 0, it indicates that there is no edge with a lower bound in the edge of this operation. This means that the edge of the lower bound is full, so the fee flow is terminated directly.
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define eps 1e-9 # define pi acos (-1.0) using namespace std; # define ll int # define inf 0x3f3f3f # define Inf 0x3FFFFFFFFFFFFFFFLL # define N 105 # define M 1005 struct Edge {ll from, to, cap, cost, nex; Edge () {} Edge (ll from, ll to, ll cap, ll cost, ll next): from (from), to (to), cap (cap), cost (cost ), nex (next) {}} edges [M <1]; ll head [N], edgenum; ll d [N], a [N], p [N]; bool inq [N]; void add (ll from, ll to, ll cap, ll cost) {edges [edgenum] = Edge (from, to, cap, cost, head [from]); head [from] = edgenum ++; edges [edgenum] = Edge (to, from, 0,-cost, head [to]); head [to] = edgenum ++;} bool spfa (ll s, ll t, ll & flow, ll & cost) {for (ll I = 0; I <= t; I ++) d [I] = inf; memset (inq, 0, sizeof inq); queue
Q; q. push (s); d [s] = 0; a [s] = inf; while (! Q. empty () {ll u = q. front (); q. pop (); inq [u] = 0; for (ll I = head [u]; ~ I; I = edges [I]. nex) {Edge & e = edges [I]; if (e. cap & d [e. to]> d [u] + e. cost) {d [e. to] = d [u] + e. cost; p [e. to] = I; a [e. to] = min (a [u], e. cap); if (! Inq [e. to]) {inq [e. to] = 1; q. push (e. to) ;}}}if (d [t]> 0) return false; cost + = d [t] * a [t]; flow + = a [t]; ll u = t; while (u! = S) {edges [p [u]. cap-= a [t]; edges [p [u] ^ 1]. cap + = a [t]; u = edges [p [u] ^ 1]. to;} return true;} ll Mincost (ll s, ll t) {// return minimum cost ll flow = 0, cost = 0; while (spfa (s, t, flow, cost); return cost;} void init () {memset (head,-1, sizeof head); edgenum = 0;} int n, m; int mp [55] [55]; int h [55], l [55]; void input () {scanf ("% d", & n, & m); for (int I = 1; I <= n; I ++) for (int j = 1; j <= m; j ++) scanf ("% d", & mp [I] [j]); for (int I = 1; I <= n; I ++) scanf ("% d ", & h [I]); for (int I = 1; I <= m; I ++) scanf ("% d", & l [I]);} # define hehe 100000int main () {int T, I, j; scanf ("% d", & T); while (T --) {input (); init (); int from = 0, to = n + m + 1; int les = 0; for (I = 1; I <= n; I ++) {les + = h [I]; add (from, I, h [I],-hehe); add (from, I, inf, 0 );} for (I = 1; I <= m; I ++) {les + = l [I]; add (n + I, to, l [I], -hehe); add (n + I, to, inf, 0);} for (I = 1; I <= n; I ++) for (j = 1; j <= m; j ++) add (I, n + j, 1, mp [I] [j]); printf ("% d \ n ", mincost (from, to) + hehe * les);} return 0;}/* http://acdream.info/onecontest/1080#problem-Hhttp://paste.ubuntu.com/7930356/#userconsent */