Pool construction

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

题意:

  给你一个图,

  草地用#号表示,洞用 . 表示.你可以吧草改成洞,这样每格话费d,也可以把洞填上草,话费f.最后还要在草与洞之间修上围栏每边话费b.

  整个图边缘都必须是草.

题解:

  最小割

  S-草 (边缘的草权值为无穷否则为d,表示吧这条边切断的花费)

  洞-T (不在边缘的洞与其T相连,权值为f)

  相邻的洞与草之间连双向边, 表示洞变草,草变洞的花费

  跑最大流算法求最小割就好了

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include<queue>
using namespace std;
const int N = 1e6+, M = , mod = 1e9+;
typedef long long ll;
//不同为1,相同为0 int n,m,b,F,ans,D,S=,T=;
char mp[][];
int ss[][] = {,,,};
int check(int x,int y) {
if(x<||y<||x>n||y>m) return ;
return ;
}
namespace NetFlow
{
const int MAXN=+,MAXM=,inf=1e9;
struct Edge
{
int v,c,f,nx;
Edge() {}
Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {}
} E[MAXM];
int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],N,sz;
void init(int _n)
{
N=_n,sz=; memset(G,-,sizeof(G[])*N);
}
void add(int u,int v,int c)
{
E[sz]=Edge(v,c,,G[u]); G[u]=sz++;
E[sz]=Edge(u,,,G[v]); G[v]=sz++;
swap(u,v);
E[sz]=Edge(v,c,,G[u]); G[u]=sz++;
E[sz]=Edge(u,,,G[v]); G[v]=sz++;
}
int ISAP(int S,int T)
{//S -> T
int maxflow=,aug=inf,flag=false,u,v;
for (int i=;i<N;++i)cur[i]=G[i],gap[i]=dis[i]=;
for (gap[S]=N,u=pre[S]=S;dis[S]<N;flag=false)
{
for (int &it=cur[u];~it;it=E[it].nx)
{
if (E[it].c>E[it].f&&dis[u]==dis[v=E[it].v]+)
{
if (aug>E[it].c-E[it].f) aug=E[it].c-E[it].f;
pre[v]=u,u=v; flag=true;
if (u==T)
{
for (maxflow+=aug;u!=S;)
{
E[cur[u=pre[u]]].f+=aug;
E[cur[u]^].f-=aug;
}
aug=inf;
}
break;
}
}
if (flag) continue;
int mx=N;
for (int it=G[u];~it;it=E[it].nx)
{
if (E[it].c>E[it].f&&dis[E[it].v]<mx)
{
mx=dis[E[it].v]; cur[u]=it;
}
}
if ((--gap[dis[u]])==) break;
++gap[dis[u]=mx+]; u=pre[u];
}
return maxflow;
}
bool bfs(int S,int T)
{
static int Q[MAXN]; memset(dis,-,sizeof(dis[])*N);
dis[S]=; Q[]=S;
for (int h=,t=,u,v,it;h<t;++h)
{
for (u=Q[h],it=G[u];~it;it=E[it].nx)
{
if (dis[v=E[it].v]==-&&E[it].c>E[it].f)
{
dis[v]=dis[u]+; Q[t++]=v;
}
}
}
return dis[T]!=-;
}
int dfs(int u,int T,int low)
{
if (u==T) return low;
int ret=,tmp,v;
for (int &it=cur[u];~it&&ret<low;it=E[it].nx)
{
if (dis[v=E[it].v]==dis[u]+&&E[it].c>E[it].f)
{
if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
{
ret+=tmp; E[it].f+=tmp; E[it^].f-=tmp;
}
}
}
if (!ret) dis[u]=-; return ret;
}
int dinic(int S,int T)
{
int maxflow=,tmp;
while (bfs(S,T))
{
memcpy(cur,G,sizeof(G[])*N);
while (tmp=dfs(S,T,inf)) maxflow+=tmp;
}
return maxflow;
}
}
using namespace NetFlow; void Links() {
for(int i=;i<=m;i++)
add(S,i,inf);
for(int i=;i<=m;i++)
add(S,(n-)*m+i,inf);
for(int i=;i<n;i++)
add(S,(i-)*m+,inf);
for(int i=;i<n;i++)
add(S,i*m,inf);
for(int i=;i<n;i++) {
for(int j=;j<m;j++) {
if(mp[i][j]=='#') add(S,(i-)*m+j,D);
else add((i-)*m+j,T,F);
}
}
for(int i=;i<=n;i++) {
for(int j=;j<=m;j++) {
for(int k=;k<;k++) {
int xx = i+ss[k][];
int yy = j+ss[k][];
if(check(xx,yy)) {
add((i-)*m+j,(xx-)*m+yy,b);
}
}
}
}
ans+=dinic(S,T);
}
int main () {
int GG = ;
scanf("%d",&GG);
while(GG--) {
ans = ;
scanf("%d%d%d%d%d",&m,&n,&D,&F,&b);
for(int i=;i<=n;i++){
getchar();
for(int j=;j<=m;j++) scanf("%c",&mp[i][j]);
}
for(int i=;i<=m;i++)
if(mp[][i]=='.') ans+=F,mp[][i] = '#';
for(int i=;i<=m;i++)
if(mp[n][i]=='.') ans+=F,mp[n][i] = '#';
for(int i=;i<=n;i++)
if(mp[i][]=='.') ans+=F,mp[i][] = '#';
for(int i=;i<=n;i++)
if(mp[i][m]=='.') ans+=F,mp[i][m] = '#';
init();
// cout<<ans<<endl;
Links();
printf("%d\n",ans);
}
return ;
}

UVA 1515 Pool construction 最大流跑最小割的更多相关文章

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

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

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

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

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

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

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

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

  5. UVA 10480 Sabotage (网络流,最大流,最小割)

    UVA 10480 Sabotage (网络流,最大流,最小割) Description The regime of a small but wealthy dictatorship has been ...

  6. 算法笔记--最大流和最小割 && 最小费用最大流 && 上下界网络流

    最大流: 给定指定的一个有向图,其中有两个特殊的点源S(Sources)和汇T(Sinks),每条边有指定的容量(Capacity),求满足条件的从S到T的最大流(MaxFlow). 最小割: 割是网 ...

  7. UVa 1660 Cable TV Network (最大流,最小割)

    题意:求一个无向图的点连通度. 析:把每个点拆成两个,然后中间连接一个容量为1的边,然后固定一个源点,枚举每个汇点,最小割. 代码如下: #pragma comment(linker, "/ ...

  8. BZOJ 1001: [BeiJing2006]狼抓兔子【最大流/SPFA+最小割,多解】

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 23822  Solved: 6012[Submit][ ...

  9. CodeForces E. Goods transportation【最大流+dp最小割】

    妙啊 首先暴力建图跑最大流非常简单,s向每个i连流量为p[i]的边,每个i向t连流量为s[i]的边,每个i向j连流量为c的边(i<j),但是会又T又M 考虑最大流=最小割 然后dp求最小割,设f ...

随机推荐

  1. 【优化算法】遗传算法GA求解混合流水车间调度问题(附C++代码)

    00 前言 各位读者大家好,好久没有介绍算法的推文了,感觉愧对了读者们热爱学习的心灵.于是,今天我们带来了一个神奇的优化算法--遗传算法! 它的优点包括但不限于: 遗传算法对所求解的优化问题没有太多的 ...

  2. 从有约束条件下的凸优化角度思考神经网络训练过程中的L2正则化

    从有约束条件下的凸优化角度思考神经网络训练过程中的L2正则化 神经网络在训练过程中,为应对过拟合问题,可以采用正则化方法(regularization),一种常用的正则化方法是L2正则化. 神经网络中 ...

  3. Mac OS X10.9安装的Python2.7升级Python3.4步骤详解

    Mac OS X10.9安装的Python2.7升级Python3.4步骤详解 Mac OS X10.9默认带了Python2.7,不过现在Python3.4.0出来了,如果想使用最新版本,赶紧升级下 ...

  4. QlikSense系列(4)——QlikSense管理

    QlikSense管理主要通过QMC界面,在安装成功后,首先需要导入用户,QlikSense本身不能创建和验证用户,只能借助第三方系统, 笔者只使用过Windows账户和AD域用户: 1.Window ...

  5. Jquery 重置表单

    1.重置表单回初始状态 $('#fromid')[0].reset(); 此方法一步到位,不需要一个个的去赋值为空

  6. How to solve a login problem of SQL Server?

    Sometimes when we attempting to login the SQL Server 20xx Management Studio, when we type in the cor ...

  7. 在Hibernate映射文件里配置Sequence

    <!--注意该id的数据类型以及<generator>节点下的<param>节点的写法--> <id name="id" type=&qu ...

  8. 最简单的一致性Hash算法实现

    import java.util.Collection;import java.util.SortedMap;import java.util.TreeMap; public class Consis ...

  9. 把pcl的VTK显示融合到MFC(代码找原作者)

    转自PCL中国,原文链接:http://www.pclcn.org/bbs/forum.php?mod=viewthread&tid=223&extra=page%3D1 本人做了少量 ...

  10. java学习笔记1——继承

    通过在类的声明中加入extends子句创建一个子类并继承父类的成员变量和方法.如: class SubClass extends SuperClass{ ... } 若SuperClass是另一个类的 ...