题目

Source

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

Description

You are working for the International Company for Pool Construction, a construction company which specializes in building swimming pools. A new client wants to build several new pool areas. A pool area is a rectangular grid of w × h square patches, consisting of zero or more (possibly disconnected) pools. A pool consists of one or multiple connected hole patches, which will later be filled with water. In the beginning, you start with a piece of land where each patch is either a hole in the ground (’.’) or flat grass (’#’). In order to transform this land into a pool area, you must adhere to the following:
• You can leave a patch as it is. This costs nothing.
• If the patch is grass in the beginning, you can dig a hole there. This costs d EUR.
• If the patch is a hole in the beginning, you can fill the hole and put grass on top. This costs f EUR.
• You must place special boundary elements along each edge running between a final grass patch and a final hole patch, to ensure that water does not leak from the pool. This costs b EUR per boundary element.
• The outermost rows and columns of the pool area must always be grass.
You are given the task of calculating the cost of the cheapest possible pool area given the layout of the existing piece of land.

Input

On the first line a positive integer: the number of test cases, at most 100. After that per test case:
• one line with two integers w and h (2 ≤ w, h ≤ 50): the width and height of the building site.
• one line with three integers d, f and b (1 ≤ d, f, b ≤ 10000): the costs for digging a new hole, filling an existing hole, and building a boundary element between a pool and grass patch.
• h lines of w characters each, denoting the layout of the original building site.

Output

Per test case:
• one line with an integer: the cost of building the cheapest possible pool area from the original piece of land.

Sample Input

3
3 3
5 5 1
#.#
#.#
###
5 4
1 8 1
#..##
##.##
#.#.#
#####
2 2
27 11 11
#.
.#

Sample Output

9
27
22

分析

题目大概说一个n*m的土地,土地上每一个格子要嘛是洞要嘛是草地,可以花费d的价钱把草地挖成洞,或者花费f的价钱把洞填成草地,但是要保证土地的边界是草地。之后会在洞的外围围篱笆,每单位篱笆花费b。问最少的总花费。

  • 这题相当于要把土地划分到两个集合,草地和洞。
  • 原本是草地的划分到草地的代价是0,而原本是洞的划分到草地代价是f;划分到洞同理。不过,由于土地边界必须是草地,所以对于边界划分为洞的代价应该为无穷大。
  • 对于两个相邻的地,如果一个划分到洞另一个划分到草地,那就会产生b的费用。

于是就是最小割,二者选一,不同产生费用的模型。。

  1. 新建源点和汇点,并把各个地看成点
  2. 源点向所有是草地的点连容量d的边
  3. 所有是洞的点向汇点连容量f的边
  4. 源点向所有土地外围的点连容量INF的边
  5. 对于相邻的两点,之间连容量b的边
  6. 最小割即为答案

代码

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 2555
#define MAXM 2555*2555 struct Edge{
int v,cap,flow,next;
}edge[MAXM];
int vs,vt,NE,NV;
int head[MAXN]; void addEdge(int u,int v,int cap){
edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=0;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].v=u; edge[NE].cap=0; edge[NE].flow=0;
edge[NE].next=head[v]; head[v]=NE++;
} int level[MAXN];
int gap[MAXN];
void bfs(){
memset(level,-1,sizeof(level));
memset(gap,0,sizeof(gap));
level[vt]=0;
gap[level[vt]]++;
queue<int> que;
que.push(vt);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(level[v]!=-1) continue;
level[v]=level[u]+1;
gap[level[v]]++;
que.push(v);
}
}
} int pre[MAXN];
int cur[MAXN];
int ISAP(){
bfs();
memset(pre,-1,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=0,aug=INF;
gap[0]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[u]==level[v]+1){
flag=true;
pre[v]=u;
u=v;
//aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
aug=min(aug,edge[i].cap-edge[i].flow);
if(v==vt){
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]){
edge[cur[u]].flow+=aug;
edge[cur[u]^1].flow-=aug;
}
//aug=-1;
aug=INF;
}
break;
}
}
if(flag) continue;
int minlevel=NV;
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==0) break;
level[u]=minlevel+1;
gap[level[u]]++;
u=pre[u];
}
return flow;
} char map[55][55];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&m,&n);
int d,f,b;
scanf("%d%d%d",&d,&f,&b);
for(int i=0; i<n; ++i){
for(int j=0; j<m; ++j){
scanf(" %c",&map[i][j]);
}
} vs=n*m; vt=vs+1; NV=vt+1; NE=0;
memset(head,-1,sizeof(head)); for(int i=0; i<n; ++i){
for(int j=0; j<m; ++j){
if(i==0 || i==n-1 || j==0 || j==m-1) addEdge(vs,i*m+j,INF);
if(map[i][j]=='#') addEdge(vs,i*m+j,d);
else addEdge(i*m+j,vt,f);
if(i+1<n){
addEdge(i*m+j,(i+1)*m+j,b);
addEdge((i+1)*m+j,i*m+j,b);
}
if(j+1<m){
addEdge(i*m+j,i*m+j+1,b);
addEdge(i*m+j+1,i*m+j,b);
}
}
}
printf("%d\n",ISAP());
}
return 0;
}

UVa1515 Pool construction(最小割)的更多相关文章

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

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

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

    输入一个字符矩阵,'.'代表洞,'#'代表草地.可以把草改成洞花费为d,或者把洞改成草花费为f,最后还要在草和洞之间修围栏花费为b. 首先把最外一圈的洞变成草,并累加花费. 增加一个源点和一个汇点,源 ...

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

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

  4. UVA1515 Pool construction (最小割模型)

    如果不允许转化'#'和'.'的话,那么可以直接在'#'和'.'之间连容量为b的边,把所有'#'和一个源点连接, 所有'.'和一个汇点连接,流量不限,那么割就是建围栏(分割'#'和'.')的花费. 问题 ...

  5. Uva1515 Pool construction

    Time Limit: 3000MS64bit IO Format: %lld & %llu 网络流 最小割 心生绝望,用了好久的网络流模板居然是错的. ↑居然之前还侥幸能过一堆(并不)题. ...

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

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

  7. UVa 1515 (最小割) Pool construction

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

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

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

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

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

随机推荐

  1. [Android Pro] Service (startservice , bindservice , unbindservice, stopService)

    1: startService -------stopService (this will call onDestroy) 2: bindService -------unbindService    ...

  2. android viewPager 切换页面时防止fragment重新加载

    把限制页面数设置成应用一共的页面数就可以了 ViewPager.setOffscreenPageLimit(3);

  3. 三、jQuery--jQuery基础--jQuery基础课程--第10章 jQuery UI型插件

    1.拖曳插件——draggable 拖曳插件draggable的功能是拖动被绑定的元素,当这个jQuery UI插件与元素绑定后,可以通过调用draggable()方法,实现各种拖曳元素的效果,调用格 ...

  4. MyEclipse破解(MEGen.java)

    步骤: 1.将MEGen.java粘贴到任意web项目下,运行结果如下: 2.输入注册名:如sun,得到注册码: 3.Window  >>  Preference  >>  S ...

  5. myaql常用函数

    一.数学函数 abs(x)   返回x的绝对值 bin(x)   返回x的二进制(oct返回八进制,hex返回十六进制) ceiling(x)   返回大于x的最小整数值 exp(x)   返回值e( ...

  6. Cocoapods 更新后 使用

    platform:ios,'8.0'target 'APPNAME' do pod 'SMSSDK' pod 'MBProgressHUD', '0.9.1' pod 'AFNetworking', ...

  7. C# 中的Singleton模式

    一般写Singleton基本都是一下这个套路 class Singleton { public static Singleton instance; private Singleton() { } p ...

  8. OpenCV-paper detection & perspective transformation 相关资料

    经过一段时间的搜索,决定把搜过的资料都汇集在此,以免重复劳动,几乎来自stackoverflow OpenCV C++/Obj-C: Detecting a sheet of paper / Squa ...

  9. HDU1502 Regular Words

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1502 思路:当只有两个数时,可以用卡特兰数做,当三个数时,没想到卡特兰数的做法.可以使用动态规划. 状态转 ...

  10. 攻城狮在路上(贰) Spring(四)--- Spring BeanFactory简介

    BeanFactory时Spring框架最核心的接口,它提供了高级IoC的配置机制,使管理不同类型的Java对象成为了可能.我们一般称BeanFactory为IoC容器.BeanFactory是Spr ...