• 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

  • 相关阅读:
    KL散度(相对熵)和交叉熵的区别
    将模型从 PyTorch 导出到 ONNX 并使用 ONNX Runtime 运行
    Numpy Boolean Indexing Mask(Numpy 布尔索引掩码 )
    python PIL 图像处理库(Pillow)简介
    YOLO v3 网络结构和源码详解
    PyTorch 下使用 Tensorboard
    Python vars() 函数
    python 的 Tqdm 模块
    Pytorch 中的模式设置:model.eval() 和 model.train()
    Pytorch 中的 zero_grad 使用方法
  • 原文地址:https://www.cnblogs.com/yousiki/p/6230632.html
Copyright © 2020-2023  润新知