码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3144 [Hnoi2013]切糕

时间:2015-02-16 11:38:46      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:

Orz 黄学长好腻害!

首先题目就是要求在一个P*Q的格子里填数,不同的数代价不同,要求相邻的格子差小于D,求最小代价。

最小割模型,我们把一个格子拆成R个点

(x, y, z)向(x, y, z + 1)连边,边权f(x, y, z + 1)

(x, y, z)向(x + dx, y + dy, z - d)连边,边权inf

然后割一下就好了,正确性嘛。。。应该是对的。。。

 

技术分享
  1 /**************************************************************
  2     Problem: 3144
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:596 ms
  7     Memory:14056 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13  
 14 using namespace std;
 15 const int N = 100005;
 16 const int M = N * 10;
 17 const int inf = 1e9;
 18 const int dx[4] = {0, 0, 1, -1};
 19 const int dy[4] = {1, -1, 0, 0};
 20  
 21 struct edge {
 22   int next, to, f;
 23   edge() {}
 24   edge(int _n, int _t, int _f) : next(_n), to(_t), f(_f) {}
 25 } e[M];
 26  
 27 int first[N], tot = 1;
 28 int n, S, T, P, Q, R, D;
 29 int f[45][45][45];
 30 int d[N], q[N];
 31  
 32 inline int read() {
 33   int x = 0, sgn = 1;
 34   char ch = getchar();
 35   while (ch < 0 || 9 < ch) {
 36     if (ch == -) sgn = -1;
 37     ch = getchar();
 38   }
 39   while (0 <= ch && ch <= 9) {
 40     x = x * 10 + ch - 0;
 41     ch = getchar();
 42   }
 43   return sgn * x;
 44 }
 45  
 46 inline void Add_Edges(int x, int y, int z) {
 47   e[++tot] = edge(first[x], y, z), first[x] = tot;
 48   e[++tot] = edge(first[y], x, 0), first[y] = tot;
 49 }
 50  
 51 inline int p(int x, int y, int z) {
 52   return z == 0 ? S : (z - 1) * P * Q + (x - 1) * Q + y;
 53 }
 54  
 55 void build_graph() {
 56   int i ,j, k, l, X, Y;
 57   for (i = 1; i <= P; ++i)
 58     for (j = 1; j <= Q; ++j) {
 59       for (k = 1; k <= R; ++k) {
 60     Add_Edges(p(i, j, k - 1), p(i, j, k), f[i][j][k]);
 61     if (k > D)
 62       for (l = 0; l < 4; ++l) {
 63         X = i + dx[l], Y = j + dy[l];
 64         if (X < 1 || Y < 1 || X > P || Y > Q) continue;
 65         Add_Edges(p(i, j, k), p(X, Y, k - D), inf);
 66       }
 67       }
 68       Add_Edges(p(i, j, R), T, inf);
 69     }
 70 }
 71  
 72 #define y e[x].to
 73 #define p q[l]
 74 bool bfs() {
 75   int l, r, x;
 76   memset(d, -1, sizeof(d));
 77   d[q[1] = S] = 1;
 78   for (l = r = 1; l != r + 1; ++l)
 79     for (x = first[p]; x; x = e[x].next)
 80       if (!~d[y] && e[x].f) {
 81     d[q[++r] = y] = d[p] + 1;
 82     if (y == T) return 1;
 83       }
 84   return 0;
 85 }
 86 #undef p
 87  
 88 int dfs(int p, int lim) {
 89   if (p == T || !lim) return lim;
 90   int x, tmp, rest = lim;
 91   for (x = first[p]; x && rest; x = e[x].next) 
 92     if (d[y] == d[p] + 1 && ((tmp = min(e[x].f, rest)) > 0)) {
 93       rest -= (tmp = dfs(y, tmp));
 94       e[x].f -= tmp, e[x ^ 1].f += tmp;
 95       if (!rest) return lim;
 96     }
 97   if (rest) d[p] = -1;
 98   return lim - rest;
 99 }
100 #undef y
101  
102 int Dinic() {
103   int res = 0;
104   while (bfs())
105     res += dfs(S, inf);
106   return res;
107 }
108  
109 int main() {
110   int i, j, k;
111   P = read(), Q = read(), R = read(), D = read();
112   S = P * Q * R + 1, T = S + 1;
113   for (i = 1; i <= R; ++i)
114     for (j = 1; j <= P; ++j)
115       for (k = 1; k <= Q; ++k)
116     f[j][k][i] = read();
117   build_graph();
118   printf("%d\n", Dinic());
119   return 0;
View Code

 

BZOJ3144 [Hnoi2013]切糕

标签:

原文地址:http://www.cnblogs.com/rausen/p/4293877.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!