Reprinted please indicate the source: Thank youHttp://blog.csdn.net/lyy289065406/article/details/6742534
General question:
There are n suppliers, M shopkeepers, and K items. Each supplier has known the supply of each item, and each shopkeeper has known the demand for each item. It takes different costs to ship different goods from different suppliers to different shopkeepers, it is also known that the unit cost from the supplier MJ to the kind type of goods to the unit cost required by the shopkeeper Ni.
Q: Does the supply meet the demand? If yes, what is the minimum freight?
Solution:
Fees flow problems.
(1) Input Format
Before thinking about how to solve the problem, let's first talk about the input format. Because the input format of this question is inconsistent with the direction of the graph constructed during the problem solving, you must note that. Take example 1:
(2) Question Analysis and disassembly:
A. First, we should solve the problem of "Whether the supply meets the demand.
To satisfy the total supply demand, the total supply of each item must satisfy the total demand respectively. If one of the items is not satisfied, the supply is in short supply and the data of this group is not available, -1 should be output. However, you must note that only one tag can be used after no solution is found here, but you must continue the input. Otherwise, all the subsequent data results will be wrong once the input is interrupted.
You must know that "the total supply of each item meets the total demand separately", and sum the supply of the kind items of all suppliers. ksupp [kind], sum the demand for all shopkeepers for kind items kneed [kind], and then compare ksupp [kind] With kneed [kind.
The calculation of the minimum cost flow is based on "supply equals to demand" or "supply exceeds demand.
B. minimum fees
It is not easy to directly find "mintotalcost for transporting all items from all suppliers to all shopkeepers. However, it is much easier to find the "mincost [kind] minimum cost for transporting kind items from all suppliers to all shopkeepers", which translates into a classic multi-source Multi-sink billing flow, in the end, you only need to sum the minimum cost of K items and mincost [kind] To get the minimum cost of shipping all items.
In fact, the input method of the question finally requires K matrices, which implies that we need to disassemble the question.
C. Diagram
So how do I map the kind items?
To solve the problem of multi-source Multi-Sink Network, you must first construct an equivalent single-source single-Sink Network. Create super source S and super sink T, and define the number of each point as follows:
The super source s number is 0, the supplier number is from 1 to m, the shopkeeper number is from m + 1 to m + n, and the super sink T number is m + n + 1.
Make the sum point nump = m + n + 2, apply for the "cost" space of each edge, cost [nump] [nump] and "capacity" space, Cap [nump] [nump], and the initialization is all 0.
Super source s builds edges on all suppliers m, the cost is 0, the capacity is the supply of supplier J.
Each supplier builds edges for each shopkeeper. The Forward Arc cost is the kind matrix of the input data (note that the direction is different), and the capacity is the supply of supplier J; the reverse arc cost is a negative number of the Forward Arc cost, and the capacity is 0.
All shopkeepers remit t edge construction to the super store, the cost is 0, the capacity is the demand of shopkeepers I.
Note: 1. For other edges not mentioned, the cost and capacity are both 0, and the capacity is 0, indicating saturated edges or not connected.
2. Calculate the minimum cost of each item and repeat the above steps to recompose the diagram. However, the cost and cap of the bucket do not need to be released, so you can re-assign values for reuse.
D. Solving
For the graph of kind items, the spfa algorithm is used to solve the minimum cost path (augmented chain), and the capacity on the whole augmented chain of maxflow can be adjusted based on the allocated maximum flow. The Forward Arc capacity minus maxflow, the reverse arc capacity minus maxflow, and the unit cost is multiplied by maxflow.
For specific algorithm flows, refer to my poj2195 solution Report, which is basically the same. However, note that the reason why this question is not feasible is that the supply is in short supply. It is clear from the input data that the capacity of each side is greater than or equal to 0, so there is no negative weight ring, spfa still uses the while loop until there is no augmented chain.
// Memory time // 596 K 1188 MS # include <iostream> # include <queue> using namespace STD; Class solve {public: Solve (int n, int M, int K): n (n), m (M), K (k) {mintotalcost = 0; nump = N + m + 2; S = 0; t = n + m + 1; err = false; approom (); input (); compute ();}~ Solve () {If (ERR) cout <-1 <Endl; elsecout <mintotalcost <Endl; relax ();} int Inf () const {return 0x7fffffff ;} int min (int A, int B) {return a <B? A: B;} bool check (INT kind) const {return ksupp [kind]> = kneed [kind];} void approom (void ); // apply for the bucket void input (void); // enter void compute (void); // calculate mintotalcostvoid initial (INT kind); // initialize the data, reconstruct the traffic diagram bool spfa (void) of kind items; // calculate the minimum cost flow (augmented chain) void addflow (INT kind) for the current graph ); // Add traffic to the minimum fee stream, adjust the traffic and cost on the augmented chain, and accumulate the charges for items of kind mincost [kind] void relax (void ); // release space protected: int N; // Number of shopkeepers int m; // number of suppliers int K; // number of goods types int S, T; // Number of the Super source S and super sink t int nu MP; // n + M + super source S + super sink T (that is, the number of summary points) int ** supply; // supply [J] [k]: supplier J's supply of the k-th item int ** need; // need [I] [k]: The shopkeeper I's demand for the k-th item int *** inputcost; // inputcost [kind] [N] [m]: int * mincost; // The minimum expense int mintotalcost for all suppliers to deliver goods of the K type to all shopkeepers; // minimum total cost of shipping all items from all suppliers to all shopkeepers/* Number of each point in the diagram-Super source S: 0, supplier M: 1 ~ M, shopkeeper N: m + 1 ~ M + n, super aggregation T: N + m + 1 */INT ** cost; // int ** cap between any two points; // The capacity int * Dist between any two points; // The distance from the Super source to each point int * vist; // determines whether a point is in the queue int * pre; // record the precursor. u-> V, pre [v] = ubool err; // indicates the short supply of int * ksupp; // the total supply of the k-th item int * kneed; // total demand for the k-th item}; void solve: approom (void) {int I, K; /* space required for applying for the diagram and solving the problem */mincost = new int [k + 1]; ksupp = new int [k + 1]; kneed = new int [k + 1]; dist = new int [nump]; vist = new int [nump]; Pre = new int [nump]; cost = new int * [nump]; CAP = new int * [nump]; For (I = 0; I <nump; I ++) {cost [I] = new int [nump]; CAP [I] = new int [nump];} /* apply for input space */supply = new int * [M + 1]; for (I = 1; I <= m; I ++) supply [I] = new int [k + 1]; need = new int * [n + 1]; for (I = 1; I <= N; I ++) need [I] = new int [k + 1]; inputcost = new int ** [k + 1]; // K matrices for (k = 1; k <= K; k ++) {inputcost [k] = new int * [n + 1]; for (I = 1; I <= N; I ++) inputcost [k] [I] = new int [M + 1];} return;} void solve: input (void) {int I, J, K; for (I = 1; I <= N; I ++) for (k = 1; k <= K; k ++) CIN> nee D [I] [k]; for (j = 1; j <= m; j ++) for (k = 1; k <= K; k ++) cin> supply [J] [k]; for (k = 1; k <= K; k ++) for (I = 1; I <= N; I ++) for (j = 1; j <= m; j ++) CIN> inputcost [k] [I] [J]; /* calculate the total supply and demand of the K items */For (k = 1; k <= K; k ++) {ksupp [k] = 0; for (j = 1; j <= m; j ++) ksupp [k] + = supply [J] [k]; kneed [k] = 0; for (I = 1; I <= N; I ++) kneed [k] + = need [I] [k];} return;} void solve :: compute (void) {for (INT kind = 1; kind <= K; kind ++) {initial (kind); If (! Check (kind) // check the supply and demand of the k-th item {err = true; return;} while (spfa () addflow (kind ); mintotalcost + = mincost [kind];} return;} void solve: initial (INT kind) {int I, j; mincost [kind] = 0; memset (PRE, 0, sizeof (INT) * nump); for (I = 0; I <nump; I ++) // The purpose is to process the edge {memset (Cap [I], 0, sizeof (INT) * nump); memset (cost [I], 0, sizeof (INT) * nump);}/* initialize the capacity of super source s to each supplier */For (j = 1; j <= m; j ++) cap [s] [J] = supply [J] [kind]; // The capacity from supplier J to supplier J is the supply of supplier J./* initialize the capacity of each store owner to super sink T. Volume */for (I = m + 1; I <t; I ++) CAP [I] [T] = need [I-m] [kind]; // The store owner's I-to-T capacity is the shop owner's I demand/* initialize the capacity and cost of each supplier to each shop owner */for (I = m + 1; I <t; I ++) for (j = 1; j <= m; j ++) {cost [J] [I] = inputcost [kind] [I-m] [J]; // note that the cost storage method here is the opposite of the Input Storage Method Cost [I] [J] =-cost [J] [I]; // reverse arc charge CAP [J] [I] = supply [J] [kind]; // The capacity from supplier J to owner I is the supply of supplier J} return ;} bool solve: spfa (void) {for (INT I = s; I <= T; I ++) {Dist [I] = inf (); vist [I] = false;} Dist [s] = 0; queue <int> q; q. push (s); vist [s] = true; while (! Q. empty () {int u = Q. front (); For (INT v = s; v <= T; V ++) {If (Cap [u] [v] & Dist [v]> Dist [u] + cost [u] [v]) {Dist [v] = DIST [u] + cost [u] [v]; Pre [v] = u; If (! Vist [v]) {q. push (V); vist [v] = true ;}} Q. pop (); vist [u] = false;} If (Dist [T] <Inf () return true; // Dist [T] is corrected, returns false; // No augmented chain exists, spfa ends} void solve: addflow (INT kind) {int maxflow = inf (); // you can allocate the maximum stream int I; for (I = T; I! = S; I = pre [I]) maxflow = min (maxflow, Cap [pre [I] [I]); // maximum allocable stream = minimum capacity on the augmented chain for (I = T; I! = S; I = pre [I]) {CAP [pre [I] [I]-= maxflow; // adjust CAP [I] [pre [I] + = maxflow for Forward Arc capacity; // reverse arc capacity adjustment mincost [kind] + = cost [pre [I] [I] * maxflow; // minimum fee = unit fee * maximum allocable stream} return;} void solve: Relax (void) {int I, K; Delete [] mincost; Delete [] Dist; delete [] vist; Delete [] pre; Delete [] ksupp; Delete [] kneed; for (I = 0; I <nump; I ++) {Delete [] cost [I]; Delete [] Cap [I] ;}for (I = 1; I <= m; I ++) delete [] supply [I]; for (I = 1; I <= N; I ++) Delete [] Need [I]; for (k = 1; k <= K; k ++) {for (I = 1; I <= N; I ++) Delete [] inputcost [k] [I]; delete [] inputcost [k];} return;} int main (void) {int n, m, K; while (CIN> N> m> K & (n + M + k) Solve poj2516 (n, m, k); Return 0 ;}