zoukankan      html  css  js  c++  java
  • 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
    ", minCost());
    147 }

    @Author: YouSiki

  • 相关阅读:
    读《疯狂Ajax讲义》重点
    Qt Library 链接库
    html验证码
    java开发webservice
    QT TCP/IP
    Android 开发技术流程
    jquery使用
    多台服务之间共享Session
    JS 混淆加密
    html中的表格 bootstrap-table
  • 原文地址:https://www.cnblogs.com/yousiki/p/6230632.html
Copyright © 2011-2022 走看看