【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的边即可。

最终的图其实长这样:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <queue>
  5. #include <algorithm>
  6. #define P(X,Y) ((X-1)*m+Y)
  7. #define inf 1<<30
  8. using namespace std;
  9. int n,m,S,T,ans,cnt;
  10. int A[60][60],B[60][60];
  11. int to[100010],next[100010],head[100010],val[100010],d[10010];
  12. int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
  13. queue<int> q;
  14. inline void add(int a,int b,int c)
  15. {
  16. to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
  17. to[cnt]=a,val[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
  18. }
  19. inline int rd()
  20. {
  21. int ret=0,f=1; char gc=getchar();
  22. while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
  23. while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
  24. return ret*f;
  25. }
  26. inline int dfs(int x,int mf)
  27. {
  28. if(x==T) return mf;
  29. int i,temp=mf,k;
  30. for(i=head[x];i!=-1;i=next[i]) if(val[i]&&d[to[i]]==d[x]+1)
  31. {
  32. k=dfs(to[i],min(temp,val[i]));
  33. if(!k) d[to[i]]=0;
  34. temp-=k,val[i]-=k,val[i^1]+=k;
  35. if(!temp) break;
  36. }
  37. return mf-temp;
  38. }
  39. inline int bfs()
  40. {
  41. memset(d,0,sizeof(d));
  42. while(!q.empty()) q.pop();
  43. d[S]=1,q.push(S);
  44. int i,u;
  45. while(!q.empty())
  46. {
  47. u=q.front(),q.pop();
  48. for(i=head[u];i!=-1;i=next[i]) if(val[i]&&!d[to[i]])
  49. {
  50. d[to[i]]=d[u]+1;
  51. if(to[i]==T) return 1;
  52. q.push(to[i]);
  53. }
  54. }
  55. return 0;
  56. }
  57. int main()
  58. {
  59. n=rd(),m=rd(),S=0,T=2*n*m+1;
  60. int i,j,k,a,b,c;
  61. memset(head,-1,sizeof(head));
  62. for(i=1;i<=n;i++) for(j=1;j<=m;j++) A[i][j]=rd();
  63. for(i=1;i<=n;i++) for(j=1;j<=m;j++) B[i][j]=rd(),ans+=B[i][j];
  64. for(i=1;i<=n;i++) for(j=1;j<=m;j++)
  65. {
  66. if((i^j)&1)
  67. {
  68. a=P(i,j),b=P(i,j)+n*m;
  69. add(S,a,A[i][j]),add(a,b,B[i][j]);
  70. for(k=0;k<4;k++) if(i+dx[k]&&i+dx[k]<=n&&j+dy[k]&&j+dy[k]<=m)
  71. {
  72. c=P(i+dx[k],j+dy[k]),add(b,c,inf);
  73. }
  74. }
  75. else
  76. {
  77. a=P(i,j),b=P(i,j)+n*m;
  78. add(a,T,A[i][j]),add(b,a,B[i][j]);
  79. for(k=0;k<4;k++) if(i+dx[k]&&i+dx[k]<=n&&j+dy[k]&&j+dy[k]<=m)
  80. {
  81. c=P(i+dx[k],j+dy[k]),add(c,b,inf);
  82. }
  83. }
  84. }
  85. while(bfs()) ans-=dfs(0,inf);
  86. printf("%d",ans);
  87. return 0;
  88. }

【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. 关于SpringMVC Json使用

    很简单的一个东西,这里就不做过多介绍了,写一个小Demo,随手记录下. 首先,在搭好SpringMVC工程环境之后,如果想用Spring自带的Json,需要额外的添加2个JAR包: 1.jackson ...

  2. EasyUI的功能树之异步树

    最近几个项目都用到了EasyUI这个Jquery框架,目前感觉起来还是很好使的,展示效果很好,帮助文档什么的资料很多,而且互联网上Easy粉很多,大多数拥护和喜爱EasyUI的粉丝们都愿意在网络平台互 ...

  3. symfony window下的安装 安装时候出现的问题以及解决方案

    1. cmd进入DOS  , cd 到 php.exe 的目录下 2.         php -r "readfile('http://symfony.com/installer');&q ...

  4. Docker技术原理

    Docker技术原理之Linux Namespace(容器隔离) https://blog.csdn.net/songcf_faith/article/details/82748987 Docker技 ...

  5. c#直接调用ssis包实现Sql Server的数据导入功能

    调用ssis包实现Sql Server的数据导入功能网上已经有很多人讨论过,自己参考后也动手实现了一下,上一次笔者的项目中还用了一下这个功能.思前想后,决定还是贴一下增强记忆,高手请54. 1.直接调 ...

  6. Linux命令缩写的全称

    [目录|文件] ls : list(列出目录内容) pwd : print work directory(打印当前目录,现示当前工作目录的绝对路径) cd : change directory(改变目 ...

  7. SpEL、PropertyPlaceholderConfigurer与@Value、#{}、${}

    概念 SpEL:Spring EL表达式 PropertyPlaceholderConfigurer:即org.springframework.beans.factory.config.Propert ...

  8. Dubbo -- 系统学习 笔记 -- 示例 -- 负载均衡

    Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 负载均衡 在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调 ...

  9. ios开发之-- tableview/collectionview获取当前点击的cell

    方法如下: 一般collectionView 或者 tableview都有自带的点击函数,如下: , collectionView -(void)collectionView:(UICollectio ...

  10. vs2010,vs2012如何连接vss2005,vss2008

    打开vs2010.依次打开[工具]-[选项]-[源代码管理] 这个时候可以看到管理插件中有Microsoft Visual SourceSafe选项(若没有该选项,重新安装VSS即可). 连接上项目后 ...