圈地计划

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);

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 1

Sample Output

81

【数据规模】
对于100%的数据有N,M≤100

观察题目,基本与happiness相同,所以基本也就是二分图的最小割,唯一有差别的是happiness中是属于相同的得到喜悦值,而这个是属于不同集合得到喜悦值。

这一点很难,这一点很难。

最先我想的是把中间的权令为-(w1+w2),但很明显网络流跑不起负的(可见我网络流多差,这个都不知道),然后怎么办呢?很难办。

既然我们不能用负边连体现这个关系。考虑happiness,A与B点同属于一个集合就得到这个喜悦值,注意到这里指的是属于S集,T集,那么一个精妙的变换方案出现了,我们先黑白染色,对于每个黑点A,S->A:W商业,A->T:W工业,

对于每个白点B,S->B:W工业,B->T:W商业,对于每对有关系的两点A,B,A<-->B:w1+w2。

一切问题就迎刃而解了,真是一种精妙的办法啊。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <ctime>
#include <cmath>
using namespace std;
int s,t;
int n,m;
int sum=0;
int C[200][200];
int tot=1;
int fir[200000],en[200000],nex[200000],f[200000];
void ins(int a,int b,int c,int d){
nex[++tot]=fir[a];
fir[a]=tot;
en[tot]=b;
f[tot]=c; nex[++tot]=fir[b];
fir[b]=tot;
en[tot]=a;
f[tot]=d;
}
int flow;
int d[200000],now[200000],num[200000],pre[200000],his[200000];
void sap(){
flow=0;
for (int i=0;i<=t;i++){
now[i]=fir[i];
d[i]=num[i]=0;
}
num[0]=t;
int aug=0x7fffffff;
bool flag;
int i=s;
while (d[s]<t){
his[i]=aug;
flag=false;
for (int k=now[i];k;k=nex[k])
if (f[k]>0&&d[i]==d[en[k]]+1){
aug=min(aug,f[k]);
flag=true;
now[i]=k;
pre[en[k]]=i;
i=en[k];
if (i==t){
flow+=aug;
while (i!=s){
i=pre[i];
f[now[i]]-=aug;
f[now[i]^1]+=aug;
}
aug=0x7fffffff;
}
break;
}
if (flag) continue;
int k1=0,minn=t;
for (int k=fir[i];k;k=nex[k])
if (f[k]>0&&minn>d[en[k]]){
k1=k;
minn=d[en[k]];
}
now[i]=k1;
if (!--num[d[i]]) return;
d[i]=minn+1;
num[d[i]]++; if (i!=s){
i=pre[i];
aug=his[i];
}
}
}
int main(){
// freopen("2132.in","r",stdin);
// freopen("2132.out","w",stdout);
scanf("%d%d",&n,&m);
s=n*m+1;t=n*m+2;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++){
int delta;
scanf("%d",&delta);
if ((i+j)%2==0) ins(s,(i-1)*m+j,delta,0);
if ((i+j)%2==1) ins((i-1)*m+j,t,delta,0);
sum+=delta;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++){
int delta;
scanf("%d",&delta);
if ((i+j)%2==1) ins(s,(i-1)*m+j,delta,0);
if ((i+j)%2==0) ins((i-1)*m+j,t,delta,0);
sum+=delta;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++){
scanf("%d",&C[i][j]);
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m-1;j++){
ins((i-1)*m+j,(i-1)*m+j+1,C[i][j]+C[i][j+1],C[i][j]+C[i][j+1]);
sum+=C[i][j]+C[i][j+1];
}
for (int i=1;i<=n-1;i++)
for (int j=1;j<=m;j++){
ins((i-1)*m+j,i*m+j,C[i][j]+C[i+1][j],C[i][j]+C[i+1][j]);
sum+=C[i][j]+C[i+1][j];
}
sap(); printf("%d",sum-flow); return 0;
}

[BZOJ]2132: 圈地计划 最小割的更多相关文章

  1. BZOJ 2131 圈地计划(最小割+黑白染色)

    类似于happiness的一道题,容易想到最小割的做法. 但是不同的是那一道题是相邻的如果相同则有收益,这题是相邻的不同才有收益. 转化到建图上面时,会发现,两个相邻的点连的边容量会是负数.. 有一种 ...

  2. BZOJ 2132 圈地计划(最小割)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2132 题意:n*m的格子染色黑白,对于格子(i,j)染黑色则价值为A[i][j],白色为 ...

  3. 【BZOJ2132】圈地计划 最小割

    [BZOJ2132]圈地计划 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地. ...

  4. bzoj 2132 圈地计划(黑白染色,最小割)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2132 [题意] 给定n*m个区域,建工业区价值A,建商业区价值B,如果(i,j)有k个 ...

  5. bzoj 2132 圈地计划【最小割+dinic】

    对于网格图,尤其是这种要求相邻各自不同的,考虑黑白染色 对于这张染色后图来说: 对于每个黑格: 表示初始时选择商业区: s点向它连商业区收益的流量,它向t点连工业区收益的流量: 割断S侧的边说明反悔, ...

  6. bzoj 2132: 圈地计划

    #include<cstdio> #include<iostream> #include<cstring> #define M 100009 #define inf ...

  7. [BZOJ 3144] [Hnoi2013] 切糕 【最小割】

    题目链接:BZOJ - 3144 题目分析 题意:在 P * Q 的方格上填数字,可以填 [1, R] . 在 (x, y) 上填 z 会有 V[x][y][z] 的代价.限制:相邻两个格子填的数字的 ...

  8. [BZOJ 3894] 文理分科 【最小割】

    题目链接:BZOJ - 3894 题目分析 最小割模型,设定一个点与 S 相连表示选文,与 T 相连表示选理. 那么首先要加上所有可能获得的权值,然后减去最小割,即不能获得的权值. 那么对于每个点,从 ...

  9. BZOJ 2039 人员雇佣 二元关系 最小割

    题面太长了,请各位自行品尝—>人员雇佣 分析: 借用题解的描述: a.选择每个人有一个代价Ai b.如果有两个人同时选择就可以获得收益Ei,j c.如果一个人选择另一个不选会产生代价Ei,j 这 ...

随机推荐

  1. python脚本工具-1 制作爬虫下载网页图片

    参考:http://www.cnblogs.com/fnng/p/3576154.html 本文参考虫师的博客“python实现简单爬虫功能”,整理分析后抓取其他站点的图片并下载保存在本地. 抓取图片 ...

  2. Go语言Revel框架 环境搭建

    1.首先参考连个链接 http://blog.csdn.net/creak_phone/article/details/12620969 http://www.geek521.com/?p=616 2 ...

  3. 【POJ】3468 A Simple Problem with Integers

    这题用线段树轻松解了,重新用树状数组解,关键点是区间更新.公式推导如下:sum[x] = org_sum[x] + delta[1]*x + delta[2]*(x-1) + delta[x]*1   ...

  4. Java版本的删除指定目录及子目录下名叫“xxx.txt”的所有文件

    以前写过一个python版本的,但是在查找文件路径的时候出现错误,无法正确的获取到文件的路径,就造成无法删除该路径下的“xxx.txt”文件. 当时以为是windows版本系统的错误造成这个问题的,也 ...

  5. 1682. Crazy Professor(并查集)

    1628 加了些数论知识  先看下剩余类的概念 一个整数被正整数n除后,余数有n种情形:0,1,2,3,…,n-1,它们彼此对模n不同余.这表明,每个整数恰与这n个整数中某一个对模n同余.这样一来,按 ...

  6. JVM的参数设置与OutOfMemoryError异常关系

    Java堆中存放Object对象数据,例如new出来的Object.当没有任何引用指向某对象时,该对象可能被垃圾回收.有关垃圾回收算法,可参考其他有关文章,网上很多.关于对象引用,按强弱还有强引用,软 ...

  7. linux mkfs命令参数及用法详解---linux格式化文件系统命令(包括swap分区)

    mkfs 命令  linux格式化磁盘命令           linux mkfs         指令:mkfs 使用权限 : 超级使用者 使用方式 : mkfs [-V] [-t fstype] ...

  8. erlang学习笔记之基础语法

    字符串是双引号,单引号的是atom元组: 下标从1开始 X = {'test1',2,3,4}. element(1,X). 配合模式匹配,可以给元素项命名,直接不用下标标记元素项 列表增删改查 增加 ...

  9. OWASP Top 10 – 2013, 最新十大安全隐患(ASP.NET解决方法)

    OWASP(开放Web软体安全项目- Open Web Application Security Project)是一个开放社群.非营利性组织,目前全球有130个分会近万名会员,其主要目标是研议协助解 ...

  10. Selenium2Library系列 keywords 之 _SelectElementKeywords 之 get_list_items(self, locator)

    def get_list_items(self, locator): """Returns the values in the select list identifie ...