zoukankan      html  css  js  c++  java
  • [HNOI2013]切糕

    一眼最小割。

    主要是高度差不超过d的处理。

    把(x, y, z) 和 (x - d, y + dir, z + dir) 连边即可,

    花一下图就理解了。

    /**
     * Problem:[HNOI2013]-D2P3
     * Author:Shun Yao
     * Time:2013.5.29
     * Result:Accepted
     * Memo:MaxFlow
     */
    
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    
    const long Maxt = 65605, inf = 0x7f7f7f7f;
    
    long h[Maxt], p2[Maxt], sum[Maxt], s, t;
    
    long min(long x, long y) {
    	return x < y ? x : y;
    }
    
    class gnode {
    public:
    	long v, f, c;
    	gnode *op, *next;
    	gnode() {}
    	~gnode() {}
    	gnode(long V, long F, long C, gnode *o, gnode *ne):v(V), f(F), c(C), op(o), next(ne) {}
    } *g[Maxt], *now[Maxt], *p1[Maxt];
    
    void add(long x, long y, long c) {
    	g[x] = new gnode(y, 0, c, 0, g[x]);
    	g[y] = new gnode(x, 0, 0, g[x], g[y]);
    	g[x]->op = g[y];
    }
    
    long Q[Maxt], *L, *R;
    void heights() {
    	gnode *e;
    	memset(h, -1, sizeof h);
    	memset(sum, 0, sizeof sum);
    	sum[h[t] = 0] = 1;
    	R = (L = &(*Q = t)) + 1;
    	while (L != R) {
    		for (e = g[*L]; e; e = e->next)
    			if (h[e->v] == -1) {
    				++sum[h[e->v] = h[*L] + 1];
    				*(R++) = e->v;
    			}
    		++L;
    	}
    }
    
    void Sap() {
    	long i, ans, wt, w;
    	char f;
    	gnode *e;
    	heights();
    	for (i = 0; i <= t; ++i) {
    		now[i] = g[i];
    		p1[i] = 0;
    		p2[i] = -1;
    	}
    	ans = 0;
    	i = s;
    	while (h[s] < t) {
    		f = 0;
    		for (e = now[i]; e; e = e->next)
    			if (e->c > e->f && h[i] == h[e->v] + 1) {
    				now[i] = e;
    				p1[e->v] = e;
    				p2[e->v] = i;
    				i = e->v;
    				if (i == t) {
    					wt = inf;
    					for (w = t; w != s; w = p2[w])
    						wt = min(wt, p1[w]->c - p1[w]->f);
    					for (w = t; w != s; w = p2[w]) {
    						p1[w]->f += wt;
    						p1[w]->op->f -= wt;
    					}
    					ans += wt;
    					i = s;
    				}
    				f = 1;
    				break;
    			}
    		if (!f) {
    			w = t;
    			for (e = g[i]; e; e = e->next)
    				if (e->c > e->f && w > h[e->v]) {
    					w = h[e->v];
    					now[i] = e;
    				}
    			++sum[w == t ? w : ++w];
    			if (!(--sum[h[i]]))
    				break;
    			h[i] = w;
    			if (i != s)
    				i = p2[i];
    		}
    	}
    	printf("%ld", ans);
    }
    
    #define ai(x, y, z) (((x) * p + (y) - 1) * q + (z) - 1)
    int main() {
    	long p, q, r, d, i, j, k, a;
    	freopen("d2p3.in", "r", stdin);
    	freopen("d2p3.out", "w", stdout);
    	scanf("%ld%ld%ld%ld", &p, &q, &r, &d);
    	t = (s = ai(r, p, q) + 1) + 1;
    	for (i = 1; i <= r; ++i)
    		for (j = 1; j <= p; ++j)
    			for (k = 1; k <= q; ++k) {
    				scanf("%ld", &a);
    				add(ai(i - 1, j, k), ai(i, j, k), a);
    			}
    	for (i = d + 1; i < r; ++i)
    		for (j = 1; j <= p; ++j)
    			for (k = 1; k <= q; ++k) {
    				if (j > 1)
    					add(ai(i, j, k), ai(i - d, j - 1, k), inf);
    				if (j < p)
    					add(ai(i, j, k), ai(i - d, j + 1, k), inf);
    				if (k > 1)
    					add(ai(i, j, k), ai(i - d, j, k - 1), inf);
    				if (k < q)
    					add(ai(i, j, k), ai(i - d, j, k + 1), inf);
    			}
    	for (j = 1; j <= p; ++j)
    		for (k = 1; k <= q; ++k) {
    			add(s, ai(0, j, k), inf);
    			add(ai(r, j, k), t, inf);
    		}
    	Sap();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    socket的半包,粘包与分包的问题
    /dev/tty /dev/ttyS0 /dev/tty0,/dev/null区别
    23种设计模式小结
    嵌入式试题
    怎样给filter加入自己定义接口及调用
    实现Launcher默认壁纸、选择壁纸定制化功能
    javascript中的稀疏数组(sparse array)和密集数组
    【Linux学习】Linux的文件权限(一)
    HDU--5280(dp或枚举)
    UISegmentedControl UISlider
  • 原文地址:https://www.cnblogs.com/hsuppr/p/3105918.html
Copyright © 2011-2022 走看看