bzoj2132 圈地计划
来源:互联网 发布:暗黑三数据库 编辑:程序博客网 时间:2024/04/28 17:12
bzoj2132 圈地计划
Description
最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地。据了解,这块土地是一块矩形的区域,可以纵横划分为N×M块小区域。GDOI要求将这些区域分为商业区和工业区来开发。根据不同的地形环境,每块小区域建造商业区和工业区能取得不同的经济价值。更具体点,对于第i行第j列的区域,建造商业区将得到Aij收益,建造工业区将得到Bij收益。另外不同的区域连在一起可以得到额外的收益,即如果区域(I,j)相邻(相邻是指两个格子有公共边)有K块(显然K不超过4)类型不同于(I,j)的区域,则这块区域能增加k×Cij收益。经过Tiger.S教授的勘察,收益矩阵A,B,C都已经知道了。你能帮GDOI求出一个收益最大的方案么?Input
输入第一行为两个整数,分别为正整数N和M,分别表示区域的行数和列数;第2到N+1列,每行M个整数,表示商业区收益矩阵A;第N+2到2N+1列,每行M个整数,表示工业区收益矩阵B;第2N+2到3N+1行,每行M个整数,表示相邻额外收益矩阵C。第一行,两个整数,分别是n和m(1≤n,m≤100);
任何数字不超过1000的限制Output
输出只有一行,包含一个整数,为最大收益值。Sample Input
3 3
1 2 3
4 5 6
7 8 9
9 8 7
6 5 4
3 2 1
1 1 1
1 3 1
1 1 1Sample Output
81【数据规模】
对于100%的数据有N,M≤100
我觉得这个题意不错.. 特别是前两句
这道题还是挺裸的.. 就是把这个n*m的图按照点的横纵坐标特征黑白染色,黑的连源汇正好与白的连源汇相反,然后会产生额外费用的相邻点再中间连边,最后做一次最小割即可
#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>using namespace std;const int Maxn = 110;const int dx[4] = { 0, 1, 0, -1 };const int dy[4] = { 1, 0, -1, 0 };struct node { int x, y, next, c, opp;}a[Maxn*Maxn*20]; int first[Maxn*Maxn], len;int _min ( int x, int y ){ return x < y ? x : y; }void ins ( int x, int y, int c ){ len ++; int k1 = len; a[len].x = x; a[len].y = y; a[len].c = c; a[len].next = first[x]; first[x] = len; len ++; int k2 = len; a[len].x = y; a[len].y = x; a[len].c = 0; a[len].next = first[y]; first[y] = len; a[k1].opp = k2; a[k2].opp = k1;}int st, ed, h[Maxn*Maxn];int n, m;int na[Maxn][Maxn];int getnum ( int x, int y ){ return (x-1)*m+y; }bool bfs (){ queue <int> q; memset ( h, -1, sizeof (h) ); q.push (st); h[st] = 0; while ( !q.empty () ){ int x = q.front (); q.pop (); for ( int k = first[x]; k; k = a[k].next ){ int y = a[k].y; if ( h[y] == -1 && a[k].c > 0 ){ h[y] = h[x]+1; q.push (y); } } } return h[ed] > 0;}int dfs ( int x, int flow ){ if ( x == ed ) return flow; int delta = 0; for ( int k = first[x]; k; k = a[k].next ){ int y = a[k].y; if ( h[y] == h[x]+1 && a[k].c > 0 && flow-delta > 0 ){ int minf = dfs ( y, _min ( a[k].c, flow-delta ) ); delta += minf; a[k].c -= minf; a[a[k].opp].c += minf; } } if ( delta == 0 ) h[x] = -1; return delta;}int main (){ int i, j, k; scanf ( "%d%d", &n, &m ); len = 0; memset ( first, 0, sizeof (first) ); st = 0; ed = n*m+1; int sum = 0; for ( i = 1; i <= n; i ++ ){ for ( j = 1; j <= m; j ++ ){ int x; scanf ( "%d", &x ); sum += x; if ( (i+j) % 2 == 1 ) ins ( st, getnum (i,j), x ); else ins ( getnum (i,j), ed, x ); } } for ( i = 1; i <= n; i ++ ){ for ( j = 1; j <= m; j ++ ){ int x; scanf ( "%d", &x ); sum += x; if ( (i+j) % 2 == 1 ) ins ( getnum (i,j), ed, x ); else ins ( st, getnum (i,j), x ); } } for ( i = 1; i <= n; i ++ ){ for ( j = 1; j <= m; j ++ ){ scanf ( "%d", &na[i][j] ); } } for ( i = 1; i <= n; i ++ ){ for ( j = 1; j <= m; j ++ ){ for ( k = 0; k < 4; k ++ ){ int ii = i+dx[k], jj = j+dy[k]; if ( ii < 1 || ii > n || jj < 1 || jj > m ) continue; sum += na[i][j]; ins ( getnum (i,j), getnum (ii,jj), na[i][j]+na[ii][jj] ); } } } int ans = 0, delta; while ( bfs () ){ while ( delta = dfs ( st, 0x7fffffff ) ) ans += delta; } printf ( "%d\n", sum-ans ); return 0;}
- [bzoj2132]圈地计划
- BZOJ2132: 圈地计划
- bzoj2132 圈地计划
- bzoj2132 圈地计划
- BZOJ2132: 圈地计划
- bzoj2132: 圈地计划
- bzoj2132: 圈地计划
- bzoj2132 圈地计划
- 【BZOJ2132】 圈地计划 最小割
- bzoj2132: 圈地计划 最小割
- 【bzoj2132】【圈地计划】【最小割】
- BZOJ2132 圈地计划-最小割
- [BZOJ2132]圈地计划(最小割)
- bzoj2132 圈地计划(最小割)
- bzoj2132: 圈地计划(最小割)
- [BZOJ2132]圈地计划(最小割)
- 圈地计划
- 【BZOJ 2132】 圈地计划
- android之SurfaceView
- java运行原理
- 大话设计模式-享元模式
- Java泛型基础
- 修改log4j配置文件来减小Linux系统tomcat/logs目录下的catalina.out文件的大小
- bzoj2132 圈地计划
- 关于gedit的一个小问题
- 242. Valid Anagram
- 第十二周项目1.3—实现复数类中的运算符重载
- ftp自动连接登陆的批处理
- Linux内核调试方法总结
- 拦截器、过滤器、监听器、servlet
- 初学 Java Web 开发,请远离各种框架,从 Servlet 开发
- sizeof的详尽计算结构体字节数方法