Hdu4862 2014 multi-school B Questions/fee stream (in optimal cases, no more than K paths are used for coverage) (different solutions)
A digital matrix can be set to K times, and can be taken from the right or below each time. It requires (in the case of maximum benefits) to overwrite the full graph. If not, the output is-1. (Rule: if the number in the grid is equal to the number in each hop, the energy of the number is obtained, and the distance energy is consumed for each hop ). Each grid can go only once.
Select <= K paths to overwrite the entire graph.
The split point is obviously a bipartite graph.
One solution: edge (traffic, cost)
Source Vertex X edge () Y edge () X to Y. If yes, edge (1, consumption-obtained) exists ). Key Point (solving the problem of overwriting each point is just to fill the role): Add a vertex at the top of X, and link the Source Vertex (k, 0) it connects edges to all Y points ). You can run the maximum flow with the minimum cost.
Second: (thoughts on the ideas for creating images provided by zz1215)
Source Vertex X link edge () Y link edge (), Y to X. If yes, edge (1, consumption-obtained) (Note that this is backflow), each vertex I --> I 'has an edge (1,-w_inf), where w_inf is a relatively large number, you only need to make sure that the fee is "small" (he is the cheapest compared to other fees, so he must first stream this edge. Add a super Source Vertex and link the edge to the Source Vertex (K, 0 ). In the ascending K times, if the value increases continuously, the maximum value is obtained; otherwise, the BREAK is required when the descent starts. (Subtract from the previous one ).
PS: Was there a wrong positioning number at the beginning! ID (I, j) = I * m + j, not I * n + j !!!
Figure:
<喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHA + tPrC66O6PC9wPgo8cD48cHJlIGNsYXNzPQ = "brush: java;" >#include // 24 ms # include # Include # Include Using namespace std; int n, m, k; const int inf = 0x3f3f3f; int a [25] [25]; int head [500]; int e [10000] [4]; int nume = 0; void inline adde (int I, int j, int c, int w) {e [nume] [0] = j; e [nume] [1] = head [I]; head [I] = nume; e [nume] [2] = c; e [nume ++] [3] = w; e [nume] [0] = I; e [nume] [1] = head [j]; head [j] = nume; e [nume] [2] = 0; e [nume ++] [3] =-w;} int inq [500]; int d [500]; bool spfa (int & sumcost) {for (int I = 0; I <= 2 * n * m + 3; I ++) {inq [I] = 0; d [I] = inf ;} int minf = inf; queue Q; int prv [300]; int pre [300]; q. push (2 * n * m + 2); inq [2 * n * m + 2] = 1; d [2 * n * m + 2] = 0; while (! Q. empty () {int cur = q. front (); q. pop (); inq [cur] = 0; for (int I = head [cur]; I! =-1; I = e [I] [1]) {int v = e [I] [0]; if (e [I] [2]> 0 & d [v]> e [I] [3] + d [cur]) {d [v] = e [I] [3] + d [cur]; prv [v] = cur; pre [v] = I; if (! Inq [v]) {q. push (v); inq [v] = 1 ;}}} if (d [2 * n * m + 1] = inf) return 0; int cur = 2 * n * m + 1; while (cur! = 2 * n * m + 2) {minf = min (minf, e [pre [cur] [2]); cur = prv [cur];} cur = 2 * n * m + 1; while (cur! = 2 * n * m + 2) {e [pre [cur] [2]-= minf; e [pre [cur] ^ 1] [2] + = minf; cur = prv [cur];} sumcost + = d [2 * n * m + 1] * minf; return 1;} int mincost () {int sum = 0; while (spfa (sum); return sum;} void init () {nume = 0; for (int I = 0; I <= 2 * n * m + 3; I ++) {head [I] =-1 ;}} int main () {int T; scanf ("% d", & T ); for (int iii = 1; iii <= T; iii ++) {scanf ("% d", & n, & m, & k ); init (); string s; for (int I = 0; I > S; for (int j = 0; j K) {printf ("-1 \ n"); continue;} for (int I = 0; I % D: c: % d, w: % d \ n ", I, e [j] [0], e [j] [2], e [j] [3]); */printf ("% d \ n",-mincost ();} return 0 ;}
Method 2:
# Include
// 31 ms # include
# Include
# Include
Using namespace std; int n, m, k; const int inf = 0x3f3f3f; const int winf = 100000; int a [25] [25]; int head [500]; int e [20001] [4]; int nume = 0; void inline adde (int I, int j, int c, int w) {e [nume] [0] = j; e [nume] [1] = head [I]; head [I] = nume; e [nume] [2] = c; e [nume ++] [3] = w; e [nume] [0] = I; e [nume] [1] = head [j]; head [j] = nume; e [nume] [2] = 0; e [nume ++] [3] =-w;} int inq [500]; int d [500]; bool spfa (long & sumcost) {for (int I = 0; I <= 2 * n * m + 3; I ++) {inq [I] = 0; d [I] = inf ;} int prv [500]; int pre [500]; int minf = inf; queue
Q; q. push (n * m); inq [n * m] = 1; d [n * m] = 0; while (! Q. empty () {int cur = q. front (); q. pop (); inq [cur] = 0; for (int I = head [cur]; I! =-1; I = e [I] [1]) {int v = e [I] [0]; if (e [I] [2]> 0 & d [v]> e [I] [3] + d [cur]) {d [v] = e [I] [3] + d [cur]; prv [v] = cur; pre [v] = I; if (! Inq [v]) {q. push (v); inq [v] = 1 ;}}} if (d [2 * n * m + 1] = inf) return 0; int cur = 2 * n * m + 1; while (cur! = N * m) {minf = min (minf, e [pre [cur] [2]); cur = prv [cur];} cur = 2 * n * m + 1; while (cur! = N * m) {e [pre [cur] [2]-= minf; e [pre [cur] ^ 1] [2] + = minf; cur = prv [cur];} sumcost + = d [2 * n * m + 1] * (long) minf; return 1;} long mincost () {long sum = 0; long lastsum = 0; while (spfa (sum) // jumps out when the value is smaller {if (lastsum> =-sum) {return-lastsum;} lastsum =-sum;} return sum;} void init () {nume = 0; for (int I = 0; I <= 2 * n * m + 3; I ++) {head [I] =-1 ;}} int main () {int T; scanf ("% d", & T); for (int iii = 1; iii <= T; iii ++) {scanf ("% d ", & n, & m, & k); init (); string s; for (int I = 0; I
> S; for (int j = 0; j
K) {printf ("-1 \ n"); continue;} for (int I = 0; I
% D: c: % d, w: % d \ n ", I, e [j] [0], e [j] [2], e [j] [3]); */cout <-mincost ()-n * m * winf <