【BZOJ3774】最优选择

Description

小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择了的。一个点如果被选择了,那么可以得到Bij的回报,现在请你帮小N选一个最优的方案,使得回报-代价尽可能大。

Input

第一行两个正整数N,M表示方格图的长与宽。

接下来N行每行M个整数Aij表示控制的代价。

接下来N行每行M个整数Bij表示选择的回报。

Output

一个整数,表示最大的回报-代价(如果一个都不控制那么就是0)。

Sample Input

3 3
1 100 100
100 1 100
1 100 100
2 0 0
5 2 0
2 0 0

Sample Output

8

HINT

对于100%的数据,N,M<=50,Aij,Bij都是小于等于100的正整数。

题解:忠告:不要看大爷的图!大爷说的挺明白,然后自己想了一个差不多的建图方法,一看大爷的图:这啥玩应?我和大爷建的不一样啊!一定是我错了!然后试图理解大爷的建图方法,得出结论:大爷太神了,这方法我理解不了。

还是来一个不那么神的,又好想又好理解的做法吧!

黑白染色是显然的啦,对于白点,我们钦定划分到T集代表选,然后讨论所有的情况:

1.四周选,当前点不选。划分到S集,代价0。

因为四周的点是黑点,划分到S集代表不选,而将当前点直接连向四周的点即可保证当前点与T集割开,所以连从当前点到四周的点,容量inf的边。

2.四周不选,当前点选。划分到T集,代价A。

我们需要让当前点花费A的代价即可以与S集割开,所以连从S到当前点,容量为A的边即可。

3.四周不选,当前点不选。划分到S集,代价B。

我们需要让当前点花费B的代价即可以与T割开,这个条件和情况1属于【或】关系,所以我们新建点b,设原来的是点a,将1中的边改为从b到四周的点,然后连从a到b,容量为B的边即可。

最终的图其实长这样:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
#define P(X,Y) ((X-1)*m+Y)
#define inf 1<<30
using namespace std;
int n,m,S,T,ans,cnt;
int A[60][60],B[60][60];
int to[100010],next[100010],head[100010],val[100010],d[10010];
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
queue<int> q;
inline void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
to[cnt]=a,val[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
inline int dfs(int x,int mf)
{
if(x==T) return mf;
int i,temp=mf,k;
for(i=head[x];i!=-1;i=next[i]) if(val[i]&&d[to[i]]==d[x]+1)
{
k=dfs(to[i],min(temp,val[i]));
if(!k) d[to[i]]=0;
temp-=k,val[i]-=k,val[i^1]+=k;
if(!temp) break;
}
return mf-temp;
}
inline int bfs()
{
memset(d,0,sizeof(d));
while(!q.empty()) q.pop();
d[S]=1,q.push(S);
int i,u;
while(!q.empty())
{
u=q.front(),q.pop();
for(i=head[u];i!=-1;i=next[i]) if(val[i]&&!d[to[i]])
{
d[to[i]]=d[u]+1;
if(to[i]==T) return 1;
q.push(to[i]);
}
}
return 0;
}
int main()
{
n=rd(),m=rd(),S=0,T=2*n*m+1;
int i,j,k,a,b,c;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++) for(j=1;j<=m;j++) A[i][j]=rd();
for(i=1;i<=n;i++) for(j=1;j<=m;j++) B[i][j]=rd(),ans+=B[i][j];
for(i=1;i<=n;i++) for(j=1;j<=m;j++)
{
if((i^j)&1)
{
a=P(i,j),b=P(i,j)+n*m;
add(S,a,A[i][j]),add(a,b,B[i][j]);
for(k=0;k<4;k++) if(i+dx[k]&&i+dx[k]<=n&&j+dy[k]&&j+dy[k]<=m)
{
c=P(i+dx[k],j+dy[k]),add(b,c,inf);
}
}
else
{
a=P(i,j),b=P(i,j)+n*m;
add(a,T,A[i][j]),add(b,a,B[i][j]);
for(k=0;k<4;k++) if(i+dx[k]&&i+dx[k]<=n&&j+dy[k]&&j+dy[k]<=m)
{
c=P(i+dx[k],j+dy[k]),add(c,b,inf);
}
}
}
while(bfs()) ans-=dfs(0,inf);
printf("%d",ans);
return 0;
}

【BZOJ3774】最优选择 最小割的更多相关文章

  1. BZOJ 3774: 最优选择( 最小割 )

    最小割...二分染色然后把颜色不同的点的源汇反过来..然后就可以做了. 某个点(x,y): S->Id(x,y)(回报), Id(x,y)->T(代价), Id(i,j)&& ...

  2. BZOJ 3774 最优选择 (最小割+二分图)

    题面传送门 题目大意:给你一个网格图,每个格子都有$a_{ij}$的代价和$b_{ij}$的回报,对于格子$ij$,想获得$b_{ij}$的回报,要么付出$a_{ij}$的代价,要么$ij$周围四联通 ...

  3. bzoj3774 最优选择

    题目描述: 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择了的.一个点如果被选择了,那么可以得到Bi ...

  4. ZOJ 2676 Network Wars(最优比例最小割)

    Network Wars Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge Network of Bytelan ...

  5. 【bzoj3774】最优选择 网络流最小割

    题目描述 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择了的.一个点如果被选择了,那么可以得到Bij ...

  6. [BZOJ 3774] 最优选择 【最小割】

    题目链接:BZOJ - 3774 题目分析 此题与“文理分科”那道题目有些类似.都是使用最小割来求解,先加上可能获得的权值,在减掉必须舍弃的权值(最小割). 文理分科是规定每个人和 S 连就是选文,和 ...

  7. 最大流&最小割 - 专题练习

    [例1][hdu5889] - 算法结合(BFS+Dinic) 题意 \(N\)个点\(M\)条路径,每条路径长度为\(1\),敌人从\(M\)节点点要进攻\(1\)节点,敌人总是选择最优路径即最短路 ...

  8. LOJ_6045_「雅礼集训 2017 Day8」价 _最小割

    LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...

  9. cf786E ALT (最小割+倍增优化建图)

    如果把“我全都要”看作是我全不要的话,就可以用最小割解决啦 源点S,汇点T 我们试图让每个市民作为一个等待被割断的路径 把狗狗给市民:建边(S,i,1),其中i是市民 把狗狗给守卫:建边(j,T,1) ...

随机推荐

  1. 【项目管理】Project使用

    http://www.cnblogs.com/wangfupeng1988/p/3647166.html

  2. ESPCN超分辨率汇总

    Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural ...

  3. 【转】细谈Redis和Memcached的区别

    Redis的作者Salvatore Sanfilippo曾经对这两种基于内存的数据存储系统进行过比较: Redis支持服务器端的数据操作:Redis相比Memcached来说,拥有更多的数据结构和并支 ...

  4. PHP 使用redis

    <?php /*从平台获取数据库名*/ $dbname = ""; /*从环境变量里取host,port,user,pwd*/ $host = ''; $port = ''; ...

  5. centos7 安装keepalived

    node1 192.168.5.101 node2 192.168.5.102 1.安装 openssl openssl-devel yum install openssl openssl-devel ...

  6. AngularJS------报错"The selector "app-user-item" did not match any elements"

    原因:新建的组件没有在任何界面使用到 解决方法:在界面使用该组件

  7. Java重定向输出流实现程序日志

    创建一个类,在该类的main主方法中,保存System类的out成员变量为临时变量,然后创建一个新的文件输出流,并把这个输出流设置为System类新的输出流.在程序关键位置输出调试信息,这些调试信息将 ...

  8. PMP模拟考试-1

    1. A manufacturing project has a schedule performance index (SPI) of 0.89 and a cost performance ind ...

  9. 在python中重新导入模块

    重新加载模块 倘若,更改了已经在 Python shell 中导入的模块,然后重新导入该模块,Python 会认为“我已经导入了该模块,不需要再次读取该文件”,所以更改将无效. 要解决这个问题,有以下 ...

  10. redis 列表

    Redis 列表(List) Redis列表是简单的字符串列表,按照插入顺序排序.你可以添加一个元素导列表的头部(左边)或者尾部(右边) 一个列表最多可以包含 232 - 1 个元素 (4294967 ...