题目描述

“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。 通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。 Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。

输入

文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。

输出

文件中仅包含一个整数ans,代表篱笆的最短长度。
 
因为每块领地都是正方形格子,我们把相邻格子连起来,再沿着格子边缘画篱笆,可以发现:篱笆恰好把连的边割开了,这道题其实就是求最小割!把问题转换成求最大流就行了,将狼从源点连过来,将羊连向汇点。那么0怎么办?如果把它划分给狼或者羊,一定会有更优的解,那就直接把0放在狼和羊中间,这样就是S—>狼—>0—>羊—>T。然后直接跑最大流即可。
最后附上代码。
  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. using namespace std;
  8. int next[1000001];
  9. int to[1000001];
  10. int val[1000001];
  11. int head[1000001];
  12. int tot=1;
  13. int q[1000001];
  14. int s[120][120];
  15. int n,m;
  16. int S,T;
  17. int ans;
  18. int d[1000001];
  19. const int INF=0x3f3f3f3f;
  20. void add(int x,int y,int v)
  21. {
  22. tot++;
  23. next[tot]=head[x];
  24. head[x]=tot;
  25. to[tot]=y;
  26. val[tot]=v;
  27. tot++;
  28. next[tot]=head[y];
  29. head[y]=tot;
  30. to[tot]=x;
  31. val[tot]=0;
  32. }
  33. bool bfs(int S,int T)
  34. {
  35. int r=0;
  36. int l=0;
  37. memset(d,-1,sizeof(d));
  38. q[r++]=S;
  39. d[S]=0;
  40. while(l<r)
  41. {
  42. int now=q[l];
  43. for(int i=head[now];i;i=next[i])
  44. {
  45. if(d[to[i]]==-1&&val[i]!=0)
  46. {
  47. d[to[i]]=d[now]+1;
  48. q[r++]=to[i];
  49. }
  50. }
  51. l++;
  52. }
  53. if(d[T]==-1)
  54. {
  55. return false;
  56. }
  57. else
  58. {
  59. return true;
  60. }
  61. }
  62. int dfs(int x,int flow)
  63. {
  64. if(x==T)
  65. {
  66. return flow;
  67. }
  68. int now_flow;
  69. int used=0;
  70. for(int i=head[x];i;i=next[i])
  71. {
  72. if(d[to[i]]==d[x]+1&&val[i]!=0)
  73. {
  74. now_flow=dfs(to[i],min(flow-used,val[i]));
  75. val[i]-=now_flow;
  76. val[i^1]+=now_flow;
  77. used+=now_flow;
  78. if(now_flow==flow)
  79. {
  80. return flow;
  81. }
  82. }
  83. }
  84. if(used==0)
  85. {
  86. d[x]=-1;
  87. }
  88. return used;
  89. }
  90. void dinic()
  91. {
  92. while(bfs(S,T)==true)
  93. {
  94. ans+=dfs(S,INF);
  95. }
  96. }
  97. int main()
  98. {
  99. scanf("%d%d",&n,&m);
  100. S=n*m+1;
  101. T=n*m+2;
  102. for(int i=1;i<=n;i++)
  103. {
  104. for(int j=1;j<=m;j++)
  105. {
  106. scanf("%d",&s[i][j]);
  107. if(s[i][j]==2)
  108. {
  109. add(m*(i-1)+j,T,INF);
  110. }
  111. else if(s[i][j]==1)
  112. {
  113. add(S,m*(i-1)+j,INF);
  114. }
  115. }
  116. }
  117. for(int i=1;i<=n;i++)
  118. {
  119. for(int j=1;j<=m;j++)
  120. {
  121. int x=(i-1)*m+j;
  122. if(s[i][j]==1||s[i][j]==0)
  123. {
  124. if(i-1>=1&&(s[i-1][j]==2||s[i-1][j]==0))
  125. {
  126. add(x,m*(i-2)+j,1);
  127. }
  128. if(j-1>=1&&(s[i][j-1]==2||s[i][j-1]==0))
  129. {
  130. add(x,m*(i-1)+j-1,1);
  131. }
  132. if(i+1<=n&&(s[i+1][j]==2||s[i+1][j]==0))
  133. {
  134. add(x,m*i+j,1);
  135. }
  136. if(j+1<=m&&(s[i][j+1]==2||s[i][j+1]==0))
  137. {
  138. add(x,m*(i-1)+j+1,1);
  139. }
  140.  
  141. }
  142. }
  143. }
  144. dinic();
  145. printf("%d",ans);
  146. return 0;
  147. }

BZOJ1412[ZJOI2009]狼和羊的故事——最小割的更多相关文章

  1. 【BZOJ1412】[ZJOI2009]狼和羊的故事 最小割

    [BZOJ1412][ZJOI2009]狼和羊的故事 Description “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想: ...

  2. BZOJ 1412: [ZJOI2009]狼和羊的故事( 最小割 )

    显然是最小割...把狼的领地连S, 羊的领地连T, 然后中间再连边, 跑最大流就OK了 -------------------------------------------------------- ...

  3. P2598 [ZJOI2009]狼和羊的故事(最小割)

    P2598 [ZJOI2009]狼和羊的故事 说真的,要多练练网络流的题了,这么简单的网络流就看不出来... 题目要求我们要求将狼和羊分开,也就是最小割,(等等什么逻辑...头大....) 我们这样想 ...

  4. [ZJOI2009] 狼与羊的故事 - 最小割

    给定一个\(N \times M\)方格矩阵,每个格子可在\(0,1,2\)中取值.要求在方格的边上进行划分,使得任意联通块内不同时包含\(1\)和\(2\)的格子. ________________ ...

  5. BZOJ1412 ZJOI2009 狼和羊的故事 【网络流-最小割】

    BZOJ1412 ZJOI2009 狼和羊的故事 Description “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和 ...

  6. BZOJ1412 [ZJOI2009]狼和羊的故事 【最小割】

    1412: [ZJOI2009]狼和羊的故事 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3454  Solved: 1733 [Submit][ ...

  7. bzoj1412: [ZJOI2009]狼和羊的故事

    空地之间开始没有连然后一直WA...题意混乱...尴尬. #include<cstdio> #include<cstring> #include<iostream> ...

  8. LG2598/BZOJ1412 「ZJOI2009」狼和羊的故事 最小割

    问题描述 LG2598 BZOJ1412 题解 看到要把狼和羊两个物种分开 自然想到最小割. 发现\((x,y)\)可以向上下左右走以获得贡献,所以建边:\((x,y),(x-1,y)\),\((x, ...

  9. bzoj1412: [ZJOI2009]狼和羊的故事(最小割)

    传送门 首先,考虑只有狼和羊怎么办.我们把源点向所有羊连边,容$inf$,所有狼向汇点连边,容$inf$,然后羊向周围所有的狼连边,容$1$.那么,只要求一个割就能把狼和羊给分开,求一个最小割就是答案 ...

随机推荐

  1. React-菜鸟学习笔记(一)

    新公司的项目前端架构用的是react.js 之前孤陋寡闻并没听说过,想着后期开发和维护多少要会点前端的东西,就简单研究一下.个人的学习习惯能写代码的就不写文字,必要的地方加两行注释,代码一行行敲下去, ...

  2. Windows 10 配置Linux及安装Docker

    https://baijiahao.baidu.com/s?id=1607159570058814753&wfr=spider&for=pc https://blog.csdn.net ...

  3. Mysql:is not allowed to connect to this MySQL server

    连接mysql的时候发生这个错误:ERROR 1130: Host '192.168.1.110' is not allowed to connect to this MySQL server 解决方 ...

  4. CF892.B. Wrath

    ---恢复内容开始--- 题意: 有n个犯人,手上都有个长度为Li的武器,当铃响时大家同时挥动武器,只能把前面攻击范围内的敌人杀死,问最后还剩几个人. 题目传送门: [http://codeforce ...

  5. echarts使用笔记五:echarts的Zoom控件

    option = { title: { text: '趋势' }, tooltip : { trigger: 'axis', show:true, axisPointer : { // 坐标轴指示器, ...

  6. Codeforces Round #546 (Div. 2)

    http://codeforces.com/contest/1136 A #include <bits/stdc++.h> using namespace std; ; int N, K; ...

  7. Nginx三部曲(2)性能

    我们会告诉你 Nginx 如何工作及其背后的理念,还有如何优化以加快应用的性能,如何安装启动和保持运行. 这个教程有三个部分: 基本概念 —— 这部分需要去了解 Nginx 的一些指令和使用场景,继承 ...

  8. react初入门

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. Tomcat异常及解决办法——持续更新中

    公司项目,开发语言为java,中间件为Tomcat,运行过程中,从Tomcat出现了一些异常,现将异常及解决办法记录如下,仅供参考.(不断在补充中.......) 异常一: 1.日志内容 org.ap ...

  10. Mybatis+Spring整合后Mapper测试类编写

    public class UserMapperTest { private ApplicationContext applicationContext; @Before public void ini ...