There are N Customers, M warehouses, and K types of goods. It is known that each customer needs the quantity of each type of goods, each warehouse stores the quantity of each type of goods, and each warehouse carries a variety of goods to each customer's unit cost. Determine whether all warehouses can meet the needs of all customers. If possible, find the minimum total transportation cost.
Question: Because k products do not interfere with each other, the key is to separate k products. Two slack methods are provided.
# Include <iostream> using namespace STD; # define n 155 # define INF 999999int need [N] [N], store [N] [N], cost [N] [N] [N]; int A [n], B [N], visa [N], visb [N]; int match [N], dimensions [N] [N], slack; int n, m, kind, X, Y; bool find_path (int I) {visa [I] = 1; for (Int J = 1; j <= y; j ++) {If (visb [J]) continue; int temp = parts [I] [J]-(A [I] + B [J]); If (temp = 0) {visb [J] = 1; if (! Match [J] | find_path (Match [J]) {match [J] = I; return true ;}} else if (Slack> temp) slack = temp ;} return false;} void km () {int I, j; memset (B, 0, sizeof (B); memset (match, 0, sizeof (MATCH )); for (I = 1; I <= x; I ++) {A [I] = inf; For (j = 1; j <= y; j ++) if (A [I]> else [I] [J]) A [I] = else [I] [J];} for (I = 1; I <= X; I ++) {While (1) {slack = inf; memset (Visa, 0, sizeof (Visa); memset (visb, 0, sizeof (visb); If (Find_path (I) break;/* Note!: Slack is added to the vertex in the staggered tree in a, and the vertex in B is located in the staggered tree minus slack. Otherwise, TLE */For (j = 1; j <= X; j ++) if (Visa [J]) A [J] + = slack; For (j = 1; j <= y; j ++) if (visb [J]) B [J]-= slack ;}} int solve () {int I, J, K, ANS = 0; For (k = 1; k <= kind; k ++) {x = y = 0; for (I = 1; I <= N; I ++) for (j = 1; j <= need [I] [k]; j ++) A [++ x] = I; for (I = 1; I <= m; I ++) for (j = 1; j <= store [I] [k]; j ++) B [++ y] = I; memset (memory, 0, sizeof (memory ); For (I = 1; I <= x; I ++) for (j = 1; j <= y; j ++) dimensions [I] [J] = cost [k] [A [I] [B [J]; km (); for (I = 1; I <= y; I ++) ans + = matches [Match [I] [I];} return ans;} int main () {While (scanf ("% d", & N, & M, & kind) {If (! N &&! M &&! Kind) break; int I, j, k; for (I = 1; I <= N; I ++) for (j = 1; j <= kind; j ++) scanf ("% d", & need [I] [J]); for (I = 1; I <= m; I ++) for (j = 1; j <= kind; j ++) scanf ("% d", & store [I] [J]); For (k = 1; k <= kind; k ++) for (I = 1; I <= N; I ++) for (j = 1; j <= m; j ++) scanf ("% d", & cost [k] [I] [J]); For (k = 1; k <= kind; k ++) {int totalneed = 0; int totalstore = 0; for (I = 1; I <= N; I ++) totalneed + = need [I] [k]; for (I = 1; I <= m; I ++) totalstore + = store [I] [k]; If (totalstore <totalneed) {printf ("-1 \ n"); goto next ;}} printf ("% d \ n", solve (); next :;} return 0 ;}
# Include <cstdio> # include <cstring> # include <algorithm> using namespace STD; # define n 155 # define INF 999999int need [N] [N], store [N] [N], cost [N] [N] [N]; int A [n], B [N], visa [N], visb [N]; int match [N], substring [N] [N], slack [N]; int n, m, kind, X, Y; bool find_path (int I) {visa [I] = 1; for (Int J = 1; j <= y; j ++) {If (visb [J]) continue; if (distinct [I] [J] = A [I] + B [J]) {visb [J] = 1; if (-1 = match [J] | find_pat H (Match [J]) {match [J] = I; return true ;}} else if (Slack [J]> A [I] + B [J]-since [I] [J]) slack [J] = A [I] + B [J]-parts [I] [J];} return false;} void km () {int I, j, D; memset (B, 0, sizeof (B); memset (match,-1, sizeof (MATCH); for (I = 1; I <= x; I ++) for (A [I] =-INF, j = 1; j <= y; j ++) if (a [I] <distinct [I] [J]) A [I] = parts [I] [J]; for (I = 1; I <= x; I ++) {for (j = 1; j <= y; j ++) slack [J] = inf; while (1 ){ Memset (Visa, 0, sizeof (Visa); memset (visb, 0, sizeof (visb); If (find_path (I) break; For (D = inf, j = 1; j <= y; j ++) if (! Visb [J] & D> slack [J]) d = slack [J]; for (j = 1; j <= x; j ++) if (Visa [J]) A [J]-= D; For (j = 1; j <= y; j ++) if (visb [J]) B [J] + = D; else slack [J]-= D ;}} int solve () {int I, J, K, ANS = 0; for (k = 1; k <= kind; k ++) {x = y = 0; for (I = 1; I <= N; I ++) for (j = 1; j <= need [I] [k]; j ++) A [++ x] = I; for (I = 1; I <= m; I ++) for (j = 1; j <= store [I] [k]; j ++) B [++ y] = I; memset (memory, 0, sizeof (Distinct); for (I = 1; I <= x; I ++) for (j = 1; j <= y; j ++) dimensions [I] [J] =-cost [k] [A [I] [B [J]; km (); for (I = 1; I <= y; I ++) if (Match [I]! =-1) // note that match [I] can be added only when Match [I] [I];} return-ans;} int main () {While (scanf ("% d", & N, & M, & kind) {If (! N &&! M &&! Kind) break; int I, j, k; for (I = 1; I <= N; I ++) for (j = 1; j <= kind; j ++) scanf ("% d", & need [I] [J]); for (I = 1; I <= m; I ++) for (j = 1; j <= kind; j ++) scanf ("% d", & store [I] [J]); For (k = 1; k <= kind; k ++) for (I = 1; I <= N; I ++) for (j = 1; j <= m; j ++) scanf ("% d", & cost [k] [I] [J]); For (k = 1; k <= kind; k ++) {int totalneed = 0; int totalstore = 0; for (I = 1; I <= N; I ++) totalneed + = need [I] [k]; for (I = 1; I <= m; I ++) totalstore + = store [I] [k]; If (totalstore <totalneed) {printf ("-1 \ n"); goto next ;}} printf ("% d \ n", solve (); next :;} return 0 ;}