/*************************************** * *********** 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. algorithm content: Find the process of increasing the minimum cost of f. In; a companion network W (f) About f needs to be constructed; the minimum cost increment path for f in the original network needs to be converted to W (f) in the companion Network) find the most short-circuit problem from Vs to Vt. The Consortium network W (f) is constructed as the vertex in the original network, and each arc in the original network <u, v> is an arc <u, v> and <v, u> in the opposite direction. The weight of each arc <u, v> 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 to take f (0) = {0}; ② generally if the minimum cost flow obtained in the K-1 step is f (k-1 ), then construct the accompanied network W (f (k-1); ③ in W (f (k-1) to find the shortest circuit from Vs to Vt, if it does not exist then turn ⑤, convert to ④; ④ get the corresponding augmented path P in the original network G. F (k-1) on the adjustment; after the adjustment of the new Feasible Flow for f (k), turn ②; ⑤ f (k-1) for the minimum cost of the maximum flow, the algorithm is completed; algorithm testing: HDU1533, ZOJ2404, POJ2195 (Going Home); question: on a network map, there are n small people and n houses; within each unit of time, everyone can move one step horizontally or vertically to the adjacent square. For every villain, one step requires a dollar until he enters the house, in addition, each house can only accommodate one person. If you want to move n people to n different houses, you need to pay the minimum fee; **************************************** * ***********/# include <iostream> # include <cstring> # include <cstdlib> # include <cstdio> # include <climits> # include <algorithm> # include <queue> using na Mespace 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 Source Vertex int dist [M]; // The distance from the Source Vertex s to 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. // The 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 // records the coordinates of the Dwarf {int x, y;} man [N]; struct house // record the coordinates of the house {int x, y;} house [N]; void init () {sum = 0; in T 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 vertex 0 and supersink vertex. Note that + 1 is required, that is, the structure of the network stream is abstracted as for (int u = 0; u <= vertex; u ++) // The initial stream is 0, so 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 from the dwarf to 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 ;}