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;
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen