POJ 3422 Kaka's Matrix Travels
Question link
A matrix that goes from the upper left corner to the lower right corner. Each time you walk through a number, it becomes 0. To obtain this number, the sum of the obtained numbers is the largest.
Idea: similar to the graph creation method of range k coverage, we split the vertex. Each vertex has a value only once, and others have no value. We use the billing flow, an edge with a capacity of 1, a cost, and a capacity of k-1 is connected between the inbound and outbound points. The other edge is connected to the right and the bottom two points, then run the billing flow
Code:
# Include <cstdio> # include <cstring> # include <vector> # include <queue> # include <algorithm> using namespace std; const int MAXNODE = 5005; const int MAXEDGE = 100005; typedef int Type; const Type INF = 0x3f3f3f; struct Edge {int u, v; Type cap, flow, cost; Edge () {} Edge (int u, int v, Type cap, Type flow, Type cost) {this-> u = u; this-> v = v; this-> cap = cap; this-> flow = flow; this-> cost = cost ;}}; struct MCFC { Int n, m, s, t; Edge edges [MAXEDGE]; int first [MAXNODE]; int next [MAXEDGE]; int inq [MAXNODE]; Type d [MAXNODE]; int p [MAXNODE]; Type a [MAXNODE]; void init (int n) {this-> n = n; memset (first,-1, sizeof (first )); m = 0;} void add_Edge (int u, int v, Type cap, Type cost) {edges [m] = Edge (u, v, cap, 0, cost ); next [m] = first [u]; first [u] = m ++; edges [m] = Edge (v, u, 0, 0,-cost ); next [m] = first [v]; first [v] = m ++;} bool Bellmanford (int s, int t, Type & flow, Type & cost) {for (int I = 0; I <n; I ++) d [I] = INF; memset (inq, false, sizeof (inq); d [s] = 0; inq [s] = true; p [s] = s; a [s] = INF; queue <int> Q; Q. push (s); while (! Q. empty () {int u = Q. front (); Q. pop (); inq [u] = false; for (int I = first [u]; I! =-1; I = next [I]) {Edge & e = edges [I]; if (e. cap> e. flow & d [e. v]> d [u] + e. cost) {d [e. v] = d [u] + e. cost; p [e. v] = I; a [e. v] = min (a [u], e. cap-e. flow); if (! Inq [e. v]) {Q. push (e. v); inq [e. v] = true ;}}}if (d [t] = INF) return false; flow + = a [t]; cost + = d [t] * a [t]; int u = t; while (u! = S) {edges [p [u]. flow + = a [t]; edges [p [u] ^ 1]. flow-= a [t]; u = edges [p [u]. u;} return true;} Type Mincost (int s, int t) {Type flow = 0, cost = 0; while (bellmanford (s, t, flow, cost )); return cost ;}} gao; const int N = 55; const int d [2] [2] = {0, 1, 1, 0}; int n, k, g [N] [N]; int main () {while (~ Scanf ("% d", & n, & k) {gao. init (n * 2); for (int I = 0; I <n; I ++) for (int j = 0; j <n; j ++) {scanf ("% d", & g [I] [j]); gao. add_Edge (I * n + j, I * n + j + n * n, k-1, 0); gao. add_Edge (I * n + j, I * n + j + n * n, 1,-g [I] [j]);} for (int I = 0; I <n; I ++) {for (int j = 0; j <n; j ++) {for (int a = 0; a <2; a ++) {int x = I + d [a] [0]; int y = j + d [a] [1]; if (x <0 | x> = n | y <0 | y> = n) continue; int u = I * n + j, v = x * n + y; gao. add_Edge (u + n * n, v, k-1, 0) ;}} printf ("% d \ n",-gao. mincost (0, n * 2-1);} return 0 ;}
POJ 3422 Kaka's Matrix Travels (billing flow)