[Cpp]/********************************** * ************** algorithm introduction: the maximum flow of any capacity network is unique and definite, but its maximum flow f is not unique. Since the maximum flow f is not unique, if there is not only a capacity limit but also a cost of r on each arc, that is, there is a unit cost parameter on each arc, the maximum flow is guaranteed; there is also a maximum flow problem with the minimum cost, that is, the maximum flow problem with the minimum cost. algorithm idea: the method to find the maximum flow is to start from a feasible flow, find an augmented path P for this stream; adjust f along P, and try to find the augmented path for the new feasible stream until there is no augmented path; the minimum cost is required for the maximum flow: If f is the Feasible Flow with the traffic of f1, the minimum cost is p, which indicates that f is the largest increase path with the lowest cost; then, adjust f along p to get the feasible stream _ f, which is the least expensive among all feasible flows with the traffic of f1. In this way, when f is the largest stream, it is also the maximum flow of the required minimum fee; In the algorithm Rong: In the process of finding the minimum cost for f to increase the channel, we need to construct an adjoint network W (f) for f ); www.2cto.com converts the minimum cost increase path for f in the original network to the short-circuit problem from Vs to Vt in the companion network W (f) the constructor is the vertex in the original network. Each arc in the original network of www.2cto.com is changed to two arc in the opposite direction: <u, v> and <v, u>; the weight of each arc in W (f) is: if (f (u, v) <c (u, v) W (u, v) = r (u, v); else if (f (u, v) = c (u, v) W (u, v) = infinity (can be omitted ); if (f (u, v)> 0) W (v, u) =-r (u, v); else if (f (u, v) = 0) W (v, u) = infinity (can be omitted); algorithm flow: ① start with f (0) = {0 }; ② generally, if the minimum cost flow obtained in Step K-1 is f (k-1), then the constructor W (f (k-1) is constructed )); ③ In W (f (k-1) to find the most short circuit from Vs to Vt, if it does not exist, turn ⑤, there is turn ④; ④ in the original network G to obtain the corresponding augmented path P, f (k-1) on P adjustment; after the adjustment of the new feasible flow is f (k), turn ②; ⑤ f (k-1) is the minimum cost of the maximum flow, the algorithm is completed; algorithm test: HDU1533, ZOJ2404, POJ2195 (Going Home, there are n people and n houses. In each unit time, each person can move one step horizontally or vertically to the adjacent square. For every villain, one step requires a US dollar until he enters the house, and each house can only accommodate one person; ask n people to move to n different houses, and ask for the minimum fee to be paid; **************************************** * ***********/# include <iostream> # include <cstring> # include <cstdlib> # in Clude <cstdio> # include <climits> # include <algorithm> # include <queue> using namespace std; int n, m; const int N = 250; const int M = 10000; const int MAX = 0 xffffff; char coord [N] [N]; // coordinate set int pre [M]; // store the front vertex int dist [M]; // The distance from s stored to the Source vertex int inq [M]; // indicates whether each vertex is in the queue. int min_c_f; // records the residual capacity int vertex in the augmented path; // Number of vertices int sum; // minimum cost for saving struct element {int c; // capacity int f; // stream int c_f; // residual capacity int v; // value} G [N] [N]; struct man // Record dwarf coordinates {int x, y;} man [N]; struct house // record house coordinates {int x, y;} house [N]; void init () {sum = 0; int mcase, hcase; // records the number of dwarf people and house mcase = hcase = 0; for (int I = 1; I <= m; I ++) {for (int j = 1; j <= n; j ++) {cin> coord [I] [j]; if (coord [I] [j] = 'M') // records the coordinates of the Dwarf {mcase ++; man [mcase]. x = I; man [mcase]. y = j;} if (coord [I] [j] = 'H') // records the coordinates of the house {hcase ++; house [hcase]. x = I; house [hcase]. y = j ;}} vertex = mcase + hcase + 1; // Add the supersource point 0 Supervertex. Note that + 1 is abstracted into the network stream structure for (int u = 0; u <= vertex; u ++) // The initial stream is 0, therefore, you do not need to refactor W (f); {for (int v = 0; v <= vertex; v ++) {G [u] [v]. c = G [v] [u]. c = 0; G [u] [v]. c_f = G [v] [u]. c_f = 0; G [u] [v]. f = G [v] [u]. f = 0; G [u] [v]. v = G [v] [u]. v = MAX ;}for (int I = 1; I <= mcase; I ++) {G [0] [I]. v = 0; // The Authority value between the super source and the dwarf is 0G [0] [I]. c = G [0] [I]. c_f = 1; // The capacity from the Super source point to the dwarf is 1 for (int j = 1; j <= hcase; j ++) {int w = abs (house [j]. x-man [I]. x) + abs (house [j]. y-man [I]. y );/ /Calculate the distance between the dwarf and every house. G [I] [mcase + j]. v = w; // assign the distance to the corresponding weight. Note that the second subscript indicates that the subscript of the house is mcase + j ~!! G [I] [mcase + j]. c = 1; // set the capacity to 1 GB [I] [mcase + j]. c_f = G [I] [mcase + j]. c; G [mcase + j] [vertex]. v = 0; // calculate the value from each house to the supersettlement point as 0. Note that the subscript of the house is mcase + j G [mcase + j] [vertex]. c = G [mcase + j] [vertex]. c_f = 1; // set the capacity from each house to the supersettlement point to 0. Note that the subscript of the house is mcase + j }}} void SPFA (int s) // calculate the Shortest Path of the SPFA algorithm {queue <int> Q; int u; for (int I = 0; I <= vertex; I ++) // initialize {dist [I] = MAX; pre [I] =-1; inq [I] = 0;} dist [s] = 0; Q. push (s); inq [s] = 1; while (! Q. empty () {u = Q. front (); Q. pop (); inq [u] = 0; for (int I = 0; I <= vertex; I ++) // update the dist of the adjacent contact of u [], pre [], inq [] {int v = I; if (G [u] [v]. c_f = 0) // indicates that (u, v) has no edge continue; if (G [u] [v]. v = MAX) G [u] [v]. v =-G [v] [u]. v; if (dist [v]> dist [u] + G [u] [v]. v) // relaxation operation {dist [v] = dist [u] + G [u] [v]. v; pre [v] = u; if (inq [v] = 0) {Q. push (v); inq [v] = 1 ;}}}} void ford_fulkerson (int s, int t) {SPFA (s); while (pre [t]! =-1) // pre-1 indicates that no augmented path from s to t is found {// cout <dist [t] <"^_^" <endl; sum + = dist [t]; // Add the value of this shortest path to sum min_c_f = MAX; int u = pre [t], v = t; // calculate the residual capacity on the augmented path while (u! =-1) {if (min_c_f> G [u] [v]. c_f) min_c_f = G [u] [v]. c_f; v = u; u = pre [v];} u = pre [t], v = t; while (u! =-1) {G [u] [v]. f + = min_c_f; // modify the stream G [v] [u]. f =-G [u] [v]. f; G [u] [v]. c_f = G [u] [v]. c-G [u] [v]. f; // modify the residual capacity G [v] [u]. c_f = G [v] [u]. c-G [v] [u]. f; v = u; u = pre [v];} SPFA (s) ;}} int main () {// freopen ("C: \ Users \ Administrator \ Desktop \ kd.txt "," r ", stdin); while (cin> m> n, m | n) {init (); ford_fulkerson (0, vertex); // calculates the minimum fee for the maximum stream cout between the supersource vertex 0 and the supersink vertex <sum <endl ;} return 0 ;}