Title Link: http://poj.org/problem?id=3422
Description
On the n x n chessboard with a non-negative number in each grid, Kaka starts he matrix travels with SUM = 0. Kaka moves one rook from the left-upper grids to the Right-bottom one, taking care that the rook moves onl Y to the right or down. Kaka adds the number to SUM in each grid of the rook visited, and replaces it with zero. It is a difficult to know the maximum SUM Kaka can obtain for his first travel. Now Kaka is wondering, the maximum SUM He can obtain after his K-th travel. Note the SUM is accumulative during the K travels.
Input
The first line contains the integers n and K (1≤ n ≤ 50, 0≤ K ≤10) described above. The following N lines represents the matrix. You can assume the numbers in the matrix is no more than 1000.
Output
The maximum SUM Kaka can obtain after his K-th travel.
Sample Input
3 21 2 30 2 11 4 2
Sample Output
15
Source
POJ monthly--2007.10.06, Huang, Jinsong
Test Instructions:in a matrix, each lattice has a non-negative, the chess in the car from the upper left corner to the lower right corner, go k times, each can only walk one step, each time only to the right or down, after the number is the value (cost), and after a certain point, go again this point, then its cost is zero, the maximum and!
PS:Maximum flow problem of maximum cost,1, the construction of the edge: split each point into two points and then between the two points to establish two sides:The first: the cost between them is the opposite of the positive number of the split point (this can be solved with the minimum cost of the maximum flow, the final answer to a reverse number is the maximum cost), the flow is 1;The second article: The cost is 0, the flow is k-1;2, then respectively to the right, down to build a fee of 0, the flow of K side!
//maximum cost minimum flow as long as the edge is added change position . just fine.
//For maximum cost the maximum flow only need to replace the cost opposite number , the maximum flow solution with minimum cost can be
The code is as follows:
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath >using namespace Std;const int maxn = 10000;const int MAXM = 100000;const int INF = 0x3f3f3f3f;struct edge{int to, Next, cap, flow, cost; int x, y;} Edge[maxm];int Head[maxn],tol;int pre[maxn],dis[maxn];bool vis[maxn];int N, m;int map[maxn][maxn];void init () {N = MAXN ; Tol = 0; Memset (Head,-1, sizeof (head));} void Addedge (int u, int v, int cap, int cost)//left point, right endpoint, capacity, spend {edge[tol]. to = V; Edge[tol]. Cap = cap; Edge[tol]. Cost = Cost; Edge[tol]. flow = 0; Edge[tol]. Next = Head[u]; Head[u] = tol++; Edge[tol]. to = u; Edge[tol]. Cap = 0; Edge[tol]. Cost =-cost; Edge[tol]. flow = 0; Edge[tol]. Next = Head[v]; HEAD[V] = tol++;} BOOL SPFA (int s, int t) {queue<int>q; for (int i = 0; i < N; i++) {dis[i] = INF; Vis[i] = false; Pre[i] =-1; } Dis[s] = 0; Vis[s] = true; Q.push (s); while (!q.empty ()) {int u = q.front (); Q.pop (); Vis[u] = false; for (int i = head[u]; I! =-1; i = Edge[i]. Next) {int v = edge[i]. to; if (Edge[i]. cap > Edge[i]. Flow && Dis[v] > Dis[u] + edge[i]. Cost) { DIS[V] = Dis[u] + edge[i]. Cost PRE[V] = i; if (!vis[v]) {Vis[v] = true; Q.push (v); }}}} if (pre[t] = = 1) return false; else return true;} The maximum flow is returned, the cost is the minimum charge int mincostmaxflow (int s, int t, int &cost) {int flow = 0; Cost = 0; while (SPFA (s,t)) {int Min = INF; for (int i = pre[t]; i =-1; i = pre[edge[i^1].) {if (Min > Edge[i]. cap-edge[i]. Flow) Min = Edge[i]. Cap-edge[i]. Flow } for (int i = pre[t]; i =-1; i = pre[edge[i^1].) { Edge[i]. Flow + = Min; EDGE[I^1]. Flow-= Min; Cost + = Edge[i]. Cost * Min; } flow + = Min; } return flow;} int main () {int n, K; while (~SCANF ("%d%d", &n,&k)) {init ();//note for (int i = 1; I <= n; i++) {for ( int j = 1; J <= N; J + +) {scanf ("%d", &map[i][j]); }} for (int i = 1, i <= N; i++) {for (int j = 1; J <= N; j + +) { int tt = (i-1) *n+j; Addedge (Tt*2,tt*2+1,1,-map[i][j]);//split, build a negative value between the side, the flow of 1 Addedge (tt*2,tt*2+1,k-1,0);//Build a value of 0, traffic for the side of the K-1 printf ("tt:%d tt*2:%d tt*2+1:%d", tt,tt*2,tt*2+1); }//printf ("\ n"); } for (int i = 1; I <= n; i++)//Right {for (int j = 1; j < N; j + +) { int tt = (i-1) *n+j;//numbering starting from 2 Addedge (tt*2+1, (tt+1) *2,k,0); printf ("tt:%d tt*2:%d (tt+1) *2:%d\n", Tt,tt*2, (tt+1) * *); }} for (int i = 1; i < n; i++)//down {for (int j = 1; J <= N, j + +) { int tt = (i-1) *n+j; Addedge (Tt*2+1, (tt+n) *2,k,0); printf ("tt:%d tt*2:%d (tt+n) *2:%d\n", Tt,tt*2, (tt+n) * *); }} int beg = 1;//Super start int end = 2*n*n+2;//Super Meeting point Addedge (beg,2,k,0);//Super Start, capacity 1, cost 0 add Edge (2*n*n+1,end,k,0);//Super Sink point capacity is 1, cost 0 int ans = 0; Mincostmaxflow (Beg,end,ans); Mincostmaxflow (2,2*n*n+1,ans); printf ("%d\n",-ans);//The opposite number is the maximum value} return 0;
POJ 3422 Kaka ' s Matrix travels (max. Max Flow + split)