输入一个字符矩阵,'.'代表洞,'#'代表草地。可以把草改成洞花费为d,或者把洞改成草花费为f,最后还要在草和洞之间修围栏花费为b。

首先把最外一圈的洞变成草,并累加花费。

增加一个源点和一个汇点,源点连接每个草地,汇点连接每个洞。

源点与最外一圈的草地连一条容量无穷大的边,与其他草地连一条容量为d的边。表示把这条弧切断,割的容量增加d,草就会变成洞。

每个洞与汇点连一条容量为f的边。

相邻两个格子之间连一条双向边。

用最大流算法求最小割在加上之前把边界上的洞变成草的费用,就是最小花费。

用最小的费用将对象划分成两个集合的问题常常可以转换成最小割顺利解决.这道题就可以考虑将每一个点变成草地和洞分成两个集合.

如果通过合适的建边使得花费的总和等价于割的容量的话,那么为了求最小花费只要求最小割就好.

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cmath>
  4. #include <vector>
  5. #include <cstring>
  6. #include <string>
  7. #include <algorithm>
  8. #include <string>
  9. #include <set>
  10. #include <functional>
  11. #include <numeric>
  12. #include <sstream>
  13. #include <stack>
  14. #include <map>
  15. #include <queue>
  16. #pragma comment(linker, "/STACK:102400000,102400000")
  17. #define CL(arr, val) memset(arr, val, sizeof(arr))
  18.  
  19. #define ll long long
  20. #define inf 0x7f7f7f7f
  21. #define lc l,m,rt<<1
  22. #define rc m + 1,r,rt<<1|1
  23. #define pi acos(-1.0)
  24.  
  25. #define L(x) (x) << 1
  26. #define R(x) (x) << 1 | 1
  27. #define MID(l, r) (l + r) >> 1
  28. #define Min(x, y) (x) < (y) ? (x) : (y)
  29. #define Max(x, y) (x) < (y) ? (y) : (x)
  30. #define E(x) (1 << (x))
  31. #define iabs(x) (x) < 0 ? -(x) : (x)
  32. #define OUT(x) printf("%I64d\n", x)
  33. #define lowbit(x) (x)&(-x)
  34. #define Read() freopen("a.txt", "r", stdin)
  35. #define Write() freopen("b.txt", "w", stdout);
  36. #define maxn 1010
  37. #define maxv 3000
  38. #define mod 1000000000
  39. using namespace std;
  40.  
  41. struct edge
  42. {
  43. int to,cap,rev;
  44. edge(){}
  45. edge(int x,int y,int z)
  46. {
  47. to=x;
  48. cap=y;
  49. rev=z;
  50. }
  51. };
  52.  
  53. vector<edge>G[maxv];
  54. int level[maxv];
  55. int iter[maxv];
  56.  
  57. void Add_Edge(int from,int to,int cap)
  58. {
  59. G[from].push_back((edge){to,cap,G[to].size()});
  60. G[to].push_back((edge){from,,G[from].size()-});
  61. }
  62.  
  63. void bfs(int s)
  64. {
  65. memset(level,-,sizeof(level));
  66. queue<int>que;
  67. level[s]=;
  68. que.push(s);
  69. while(!que.empty())
  70. {
  71. int v=que.front();que.pop();
  72. for(int i=;i<G[v].size();i++)
  73. {
  74. edge &e=G[v][i];
  75. if(e.cap>&&level[e.to]<)
  76. {
  77. level[e.to]=level[v]+;
  78. que.push(e.to);
  79. }
  80. }
  81. }
  82. }
  83. int dfs(int v,int t,int f)
  84. {
  85. if(v==t) return f;
  86. for(int &i=iter[v];i<G[v].size();i++)
  87. {
  88. edge &e=G[v][i];
  89. if(e.cap>&&level[v]<level[e.to])
  90. {
  91. int d=dfs(e.to,t,min(f,e.cap));
  92. if(d>)
  93. {
  94. e.cap-=d;
  95. G[e.to][e.rev].cap+=d;
  96. // printf("%d %d %d\n",e.to,e.rev,G[e.to][e.rev]);
  97. return d;
  98. }
  99. }
  100. }
  101. return ;
  102. }
  103.  
  104. int max_flow(int s,int t)
  105. {
  106. int flow=;
  107. for(;;)
  108. {
  109. bfs(s);
  110. if(level[t]<) return flow;
  111. memset(iter,,sizeof(iter));
  112. int f;
  113. while((f=dfs(s,t,inf))>)
  114. flow+=f;
  115. }
  116. }
  117. char s[][];
  118. int w,h;
  119. int ID(int i,int j)
  120. {
  121. return i*w+j;
  122. }
  123. int main()
  124. {
  125. //freopen("a.txt","r",stdin);
  126. int t,d,f,b;
  127. scanf("%d",&t);
  128. while(t--)
  129. {
  130. scanf("%d%d%d%d%d",&w,&h,&d,&f,&b);
  131. for(int i=;i<w*h+;i++)
  132. G[i].clear();
  133. for(int i=;i<h;i++)
  134. {
  135. scanf("%s",s[i]);
  136. }
  137. int cost=;
  138. for(int i=;i<h;i++)
  139. {
  140. if(s[i][]=='.') {s[i][]='#';cost+=f;}
  141. if(s[i][w-]=='.') {s[i][w-]='#';cost+=f;}
  142. }
  143. for(int i=;i<w;i++)
  144. {
  145. if(s[][i]=='.') {s[][i]='#';cost+=f;}
  146. if(s[h-][i]=='.'){s[h-][i]='#';cost+=f;}
  147. }
  148. for(int i=;i<h;i++)
  149. {
  150. for(int j=;j<w;j++)
  151. {
  152. if(s[i][j]=='#')
  153. {
  154. int cap=inf;
  155. if(i>&&i<h-&&j>&&j<w-) cap=d;
  156. Add_Edge(w*h,ID(i,j),cap);
  157. if(i>) {Add_Edge(ID(i,j),ID(i-,j),b);}
  158. if(i<h-) {Add_Edge(ID(i,j),ID(i+,j),b);}
  159. if(j>) {Add_Edge(ID(i,j),ID(i,j-),b);}
  160. if(j<w-) {Add_Edge(ID(i,j),ID(i,j+),b);}
  161. }
  162. else
  163. {
  164. Add_Edge(ID(i,j),w*h+,f);
  165. if(i>) {Add_Edge(ID(i,j),ID(i-,j),b);}
  166. if(i<h-) {Add_Edge(ID(i,j),ID(i+,j),b);}
  167. if(j>) {Add_Edge(ID(i,j),ID(i,j-),b);}
  168. if(j<w-) {Add_Edge(ID(i,j),ID(i,j+),b);}
  169. }
  170. }
  171. }
  172. printf("%d\n",cost+max_flow(w*h,w*h+));
  173. }
  174. return ;
  175. }

Uva -1515 Pool construction(最小割)的更多相关文章

  1. UVA 1515 Pool construction 最大流跑最小割

    Pool construction You are working for the International Company for Pool Construction, a constructio ...

  2. UVa 1515 - Pool construction(最小割)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  3. UVALive 5905 Pool Construction 最小割,s-t割性质 难度:3

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  4. UVA 1515 Pool construction 水塘(最大流,经典)

    题意: 给一个h*w的矩阵,每个格子中是'#'和'.'两个符号之一,分别代表草和洞.现在要将洞给围起来(将草和洞分离),每条边需花费b元(即将一个洞包起来需要4边,将2个连续的洞包起来需要6边,省了2 ...

  5. UVA - 10480 Sabotage【最小割最大流定理】

    题意: 把一个图分成两部分,要把点1和点2分开.隔断每条边都有一个花费,求最小花费的情况下,应该切断那些边.这题很明显是最小割,也就是最大流.把1当成源点,2当成汇点,问题是要求最小割应该隔断那条边. ...

  6. UVa 1515 (最小割) Pool construction

    题意: 输入一个字符矩阵,'.'代表洞,'#'代表草地.可以把草改成洞花费为d,或者把洞改成草花费为f,最后还要在草和洞之间修围栏花费为b. 但要保证最外一圈是草,求最小费用. 分析: 还不是特别理解 ...

  7. 【uva 1515】Pool construction(图论--网络流最小割 模型题)

    题意:有一个水塘,要求把它用围栏围起来,每个费用为b.其中,(#)代表草,(.)代表洞,把一个草变成洞需要费用d, 把一个洞变成草需要费用f.请输出合法方案中的最小费用. 解法:(不好理解...... ...

  8. UVa1515 Pool construction(最小割)

    题目 Source https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...

  9. UVA-1515 Pool construction (最小割)

    题目大意:有一块地,分成nxm块.有的块上长着草,有的块上是荒地.将任何一块长着草的块上的草拔掉都需要花费d个力气,往任何一块荒地上种上草都需要花费f个力气,在草和荒地之间架一个篱笆需要花费b个力气, ...

随机推荐

  1. poj2718 Smallest Difference

    思路: 暴力乱搞. 实现: #include <iostream> #include <cstdio> #include <sstream> #include &l ...

  2. html----有关图像

    这一节内容可概括为:网页上插入图片,调整图片大小,使用缩略图链接至大图. 图片的三种格式:jpeg     png    gif 照片.复杂图像使用jpeg,单色图像.logo.几何图形使用png以及 ...

  3. Map接口框架图

    Java集合大致可分为Set.List和Map三种体系,其中Set代表无序.不可重复的集合:List代表有序.重复的集合:而Map则代表具有映射关系的集合.Java 5之后,增加了Queue体系集合, ...

  4. 关于Android软键盘把布局顶上去的问题

    首先说下我的需求:布局最上面是一个bar,有左上角返回按钮和标题,bar下面是一个ScrollView,里面有各种TextView和EditText, 点击下面的EditText时,不希望软键盘把ba ...

  5. raw cannot be resolved or is not a field解决办法

    解决raw文件夹问题 查看左侧项目/res文件夹下是否有raw文件夹,(一定是放到res文件夹下,raw在项目开始创建时候不会自动创建,所以要自己创建)

  6. 5.4QBXT 模拟赛 (Rank1 机械键盘 蛤蛤)

    NOIP2016提高组模拟赛 ——By wangyurzee7 中文题目名称 纸牌 杯具 辣鸡 英文题目与子目录名 cards cups spicychicken 可执行文件名 cards cups ...

  7. MFC_简易文件管理器

    练习_简易文件管理器 Edit1编辑框绑定变量,初始化内容 m_EditCtrl = L"D:\"; 添加List控件,属性设置report,OnInitDialog()函数里添加 ...

  8. QStandardItemModel

    QString("%1").arg(g_PrjMg.m_Param.stRunParaSet.wWDTTimer) ///站号参数 model = new QStandardIte ...

  9. Android反编译初步

    网上关于Android反编译的帖子很多,反编译的步骤也是很详细,本文Android反编译参考博客:https://www.cnblogs.com/dhcn/p/7120891.html 而反编译中最主 ...

  10. Javascript中的For循环

    在开发的过程中,遍历是一个经常遇到的.而for循环则是Javascript工具箱里一个好用的,也常用的工具.每个人的习惯不同,for循环的写法也不尽相同. 1.不写声明变量的写法: for(var i ...