POJ 3422 Kaka's Matrix Travels

Posted You Siki

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3422 Kaka's Matrix Travels相关的知识,希望对你有一定的参考价值。

Kaka‘s Matrix Travels
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9567   Accepted: 3888

Description

On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka moves one rook from the left-upper grid to the right-bottom one, taking care that the rook moves only to the right or down. Kaka adds the number to SUM in each grid the rook visited, and replaces it with zero. It is not difficult to know the maximum SUM Kaka can obtain for his first travel. Now Kaka is wondering what is the maximum SUM he can obtain after his Kth travel. Note the SUM is accumulative during the K travels.

Input

The first line contains two 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 are no more than 1000.

Output

The maximum SUM Kaka can obtain after his Kth travel.

Sample Input

3 2
1 2 3
0 2 1
1 4 2

Sample Output

15

Source

POJ Monthly--2007.10.06, Huang, Jinsong

[Submit]   [Go Back]   [Status]   [Discuss]

 

有一个NxN的棋盘,每个格子有一个非负整数。从左上角走到右下角,获得路径格子上的权值(只能向右或向下走),且每个格子的权值只能获得一次,可以理解为经过的格子权值置为0。可以走K次,求获得的最大权值和。

 

拆点跑最大费用最大流。

 

每个格子拆成入点和出点,入点向出点连一条容量为1,权值为格子权值的边,表示权值只能获得一次,再连一条容量无穷,权值为0的的边,表示之后可以经过但不获得权值。再按照右下的转移规则连接格子即可。做从左上格子到右下格子,最大流为K的最大费用流即可。

 

  1 #include <cstdio>
  2 #include <cstring>
  3 
  4 #define fread_siz 1024
  5 
  6 inline int get_c(void)
  7 {
  8     static char buf[fread_siz];
  9     static char *head = buf + fread_siz;
 10     static char *tail = buf + fread_siz;
 11 
 12     if (head == tail)
 13         fread(head = buf, 1, fread_siz, stdin);
 14 
 15     return *head++;
 16 }
 17 
 18 inline int get_i(void)
 19 {
 20     register int ret = 0;
 21     register int neg = false;
 22     register int bit = get_c();
 23 
 24     for (; bit < 48; bit = get_c())
 25         if (bit == -)neg ^= true;
 26 
 27     for (; bit > 47; bit = get_c())
 28         ret = ret * 10 + bit - 48;
 29 
 30     return neg ? -ret : ret;
 31 }
 32 
 33 inline int min(int a, int b)
 34 {
 35     return a < b ? a : b;
 36 }
 37 
 38 const int inf = 2e9;
 39 
 40 const int N = 55;
 41 const int M = 500005;
 42 
 43 int n, m;
 44 int s, t;
 45 int edges;
 46 int hd[M];
 47 int nt[M];
 48 int to[M];
 49 int fl[M];
 50 int vl[M];
 51 
 52 int dis[M];
 53 int pre[M];
 54 
 55 inline bool bfs(void)
 56 {
 57     static int que[M];
 58     static int inq[M];
 59     static int head, tail;
 60     
 61     memset(dis, -1, sizeof(dis));
 62     memset(inq, 0, sizeof(inq));
 63     head = 0, tail = 0;
 64     que[tail++] = s;
 65     pre[s] = -1;
 66     dis[s] = 0;
 67     inq[s] = 1;
 68     
 69     while (head != tail)
 70     {
 71         int u = que[head++], v; inq[u] = 0;
 72         for (int i = hd[u]; ~i; i = nt[i])
 73             if (dis[v = to[i]] < dis[u] + vl[i] && fl[i])
 74             {
 75                 pre[v] = i ^ 1;
 76                 dis[v] = dis[u] + vl[i];
 77                 if (!inq[v])inq[que[tail++] = v] = 1;
 78             }
 79     }
 80     
 81     return dis[t] != -1;
 82 }
 83 
 84 inline int minCost(void)
 85 {
 86     int cost = 0;
 87     
 88     while (bfs())
 89     {
 90         int flow = inf;
 91         
 92         for (int i = pre[t]; ~i; i = pre[to[i]])
 93             flow = min(flow, fl[i ^ 1]);
 94             
 95         for (int i = pre[t]; ~i; i = pre[to[i]])
 96             fl[i] += flow, fl[i ^ 1] -= flow;
 97             
 98         cost += dis[t] * flow;
 99     }
100     
101     return cost;
102 }
103 
104 inline void add(int u, int v, int f, int w)
105 {
106     nt[edges] = hd[u]; to[edges] = v; fl[edges] = f; vl[edges] = +w; hd[u] = edges++;
107     nt[edges] = hd[v]; to[edges] = u; fl[edges] = 0; vl[edges] = -w; hd[v] = edges++;
108 }
109 
110 int G[N][N];
111 
112 inline int h(int x, int y, int k)
113 {
114     return ((x - 1) * n + y) << 1 | k;
115 }
116 
117 signed main(void)
118 {
119     n = get_i();
120     m = get_i();
121     
122     for (int i = 1; i <= n; ++i)
123         for (int j = 1; j <= n; ++j)
124             G[i][j] = get_i();
125             
126     memset(hd, -1, sizeof(hd));
127     
128     s = 0, t = (n*n + 1) << 1 | 1;
129     
130     for (int i = 1; i <= n; ++i)
131         for (int j = 1; j <= n; ++j)
132             add(h(i, j, 0), h(i, j, 1), m, 0),
133             add(h(i, j, 0), h(i, j, 1), 1, G[i][j]);
134             
135     for (int i = 1; i < n; ++i)
136         for (int j = 1; j <= n; ++j)
137             add(h(i, j, 1), h(i + 1, j, 0), m, 0);
138     
139     for (int i = 1; i <= n; ++i)
140         for (int j = 1; j < n; ++j)
141             add(h(i, j, 1), h(i, j + 1, 0), m, 0);
142             
143     add(s, h(1, 1, 0), m, 0);
144     add(h(n, n, 1), t, m, 0);
145     
146     printf("%d\n", minCost());
147 }

 

@Author: YouSiki

以上是关于POJ 3422 Kaka's Matrix Travels的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3422 Kaka's Matrix Travels

POJ3422:Kaka's Matrix Travels——题解

POJ3422 Kaka&#39;s Matrix Travels 最大费用最大流

POJ3422 Kaka's Matrix Travels[?????????]

POJ 3422Kaka's Matrix Travels(最小费用最大流)

[poj] 3422 Kaka's Matrix Travels || 最小费用最大流