zoukankan      html  css  js  c++  java
  • BZOJ 3144: [Hnoi2013]切糕

    3144: [Hnoi2013]切糕

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1564  Solved: 839
    [Submit][Status][Discuss]

    Description

    Input

    第一行是三个正整数P,Q,R,表示切糕的长P、 宽Q、高R。第二行有一个非负整数D,表示光滑性要求。接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤P, 1≤y≤Q, 1≤z≤R)。 
    100%的数据满足P,Q,R≤40,0≤D≤R,且给出的所有的不和谐值不超过1000。

    Output

    仅包含一个整数,表示在合法基础上最小的总不和谐值。

    Sample Input

    2 2 2
    1
    6 1
    6 1
    2 6
    2 6

    Sample Output

    6

    HINT

    最佳切面的f为f(1,1)=f(2,1)=2,f(1,2)=f(2,2)=1

    Source

     
    [Submit][Status][Discuss]

    OTZ 最小割

    如果用$(x,y,z)$表示网络中的点,那么有两类边:

      1. $<(x,y,z),(x,y,z+1),V[x][y][z]>$

      2. $<(x,y,z),(x',y',z-D),INF>$

    求最小割即可,注意细节。

      1 #include <cstdio>
      2 #include <cstring>
      3 
      4 inline char Char(void)
      5 {
      6     static const short siz = 1024;
      7     
      8     static char buf[siz];
      9     static char *hd = buf + siz;
     10     static char *tl = buf + siz;
     11     
     12     if (hd == tl)
     13         fread(hd = buf, 1, siz, stdin);
     14     
     15     return *hd++;
     16 }
     17 
     18 inline int Int(void)
     19 {
     20     int ret = 0, neg = 0, c = Char();
     21     
     22     for (; c < 48; c = Char())
     23         if (c == '-')neg ^= true;
     24     
     25     for (; c > 47; c = Char())
     26         ret = ret * 10 + c - '0';
     27     
     28     return neg ? -ret : ret;
     29 }
     30 
     31 const int mxn = 45;
     32 const int siz = 2000005;
     33 const int inf = 1000000007;
     34 
     35 int s, t;
     36 int hd[siz];
     37 int to[siz];
     38 int fl[siz];
     39 int nt[siz];
     40 
     41 inline void add(int u, int v, int f)
     42 {
     43     static int tot = 0, init = 1;
     44     
     45     if (init)memset(hd, -1, sizeof(hd)), init = 0;
     46     
     47     nt[tot] = hd[u]; to[tot] = v; fl[tot] = f; hd[u] = tot++;
     48     nt[tot] = hd[v]; to[tot] = u; fl[tot] = 0; hd[v] = tot++;
     49 }
     50 
     51 int dep[siz];
     52 
     53 inline bool bfs(void)
     54 {
     55     static int que[siz], head, tail;
     56     memset(dep, 0, sizeof(dep));
     57     head = 0, tail = 0;
     58     que[tail++] = s;
     59     dep[s] = 1;
     60     
     61     while (head != tail)
     62     {
     63         int u = que[head++], v; 
     64         
     65         for (int i = hd[u]; ~i; i = nt[i])
     66             if (!dep[v = to[i]] && fl[i])
     67                 dep[que[tail++] = v] = dep[u] + 1;
     68     }
     69     
     70     return dep[t];
     71 }
     72 
     73 int cur[siz];
     74 
     75 inline int min(int a, int b)
     76 {
     77     return a < b ? a : b;
     78 }
     79 
     80 int dfs(int u, int f)
     81 {
     82     if (u == t || !f)
     83         return f;
     84     
     85     int used = 0, flow, v;
     86     
     87     for (int i = hd[u]; ~i; i = nt[i])
     88         if (fl[i] && dep[v = to[i]] == dep[u] + 1)
     89         {
     90             flow = dfs(v, min(fl[i], f - used));
     91             
     92             used += flow;
     93             fl[i] -= flow;
     94             fl[i^1] += flow;
     95             
     96             if (fl[i])
     97                 cur[u] = i;
     98             
     99             if (used == f)
    100                 return f;
    101         }
    102         
    103     if (!used)
    104         dep[u] = 0;
    105         
    106     return used;
    107 }
    108 
    109 inline int minCut(void)
    110 {
    111     int maxFlow = 0, newFlow;
    112     
    113     while (bfs())
    114     {
    115         memcpy(cur, hd, sizeof(cur));
    116             
    117         while (newFlow = dfs(s, inf))
    118             maxFlow += newFlow;
    119     }
    120     
    121     return maxFlow;
    122 }
    123 
    124 int P, Q, R, D, V[mxn][mxn][mxn];
    125 
    126 inline int pos(int i, int j, int k)
    127 {
    128     if (k < 1)return s;
    129     
    130     return (i - 1) * (Q * R) + (j - 1) * R + k;
    131 }
    132 
    133 const int mv[4][2] = 
    134 {
    135     {0, +1},
    136     {0, -1},
    137     {-1, 0},
    138     {+1, 0}
    139 };
    140 
    141 signed main(void)
    142 {
    143     P = Int();
    144     Q = Int();
    145     R = Int();
    146     D = Int();
    147     
    148     for (int k = 1; k <= R; ++k)
    149         for (int i = 1; i <= P; ++i)
    150             for (int j = 1; j <= Q; ++j)
    151                 V[i][j][k] = Int();
    152                 
    153     s = 0, t = P * Q * R + 1;
    154     
    155     for (int i = 1; i <= P; ++i)
    156         for (int j = 1; j <= Q; ++j)
    157         {
    158             for (int k = 1; k <= R; ++k)
    159             {
    160                 add(pos(i, j, k - 1), pos(i, j, k), V[i][j][k]);
    161                 
    162                 for (int l = 0; l < 4; ++l)
    163                 {
    164                     int x = i + mv[l][0];
    165                     int y = j + mv[l][1];
    166                     
    167                     if (x < 1 || x > P)continue;
    168                     if (y < 1 || y > Q)continue;
    169                     
    170                     if (k - D > 0)
    171                         add(pos(i, j, k), pos(x, y, k - D), inf);
    172                 }
    173             }
    174             
    175             add(pos(i, j, R), t, inf);
    176         }
    177             
    178     printf("%d
    ", minCut());
    179 }

    @Author: YouSiki

  • 相关阅读:
    二叉排序树
    堆排序
    线索化二叉树
    vue 格式化代码
    线程的理解
    声明式的服务调用 Feign
    使用锁 的理解
    zookeeper 的理解
    AQS 源码解析
    HashMap 的理解与结构
  • 原文地址:https://www.cnblogs.com/yousiki/p/6276758.html
Copyright © 2011-2022 走看看