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. Gym-101915B Ali and Wi-Fi 计算几何 求两圆交点

    题面 题意:给你n个圆,每个圆有一个权值,你可以选择一个点,可以获得覆盖这个点的圆中,权值最大的m个的权值,问最多权值是多少 题解:好像是叙利亚的题....我们画画图就知道,我们要找的就是圆与圆交的那 ...

  2. 基于mkdocs-material搭建个人静态博客

    基于mkdocs-material搭建个人纯静态博客,没有php,没有mysql 如果你只是想安安静静的放一些技术文章,发布到个人站点或github-pages,mkdocs-material很适合你 ...

  3. django 实现websocket

    一.简述:django实现websocket,之前django-websocket退出到3.0之后,被废弃.官方推荐大家使用channels. channels通过升级http协议 升级到websoc ...

  4. 第6章 服务模式 Service Interface(服务接口)

    Service Interface(服务接口) 上下文 您正在设计企业应用程序,并且需要能够通过网络使用其部分功能.此功能需要能够被各类系统使用,因此互操作性是设计的重要方面.除互操作性之外,可能还需 ...

  5. 4185 Oil Skimming 最大匹配 奇偶建图

    题目大意: 统计相邻(上下左右)的‘#’的对数. 解法: 与题目hdu1507 Uncle Tom's Inherited Land*类似,需要用奇偶建图.就是行+列为奇数的作为X集合,偶尔作为Y集合 ...

  6. Openwrt PPTP Server笔记

    1.安装PPTP opkg updateopkg install kmod-mppeopkg install pptpd 2./etc/pptpd.conf option /etc/ppp/optio ...

  7. map参数值取代

    public static String processTemplate(String tpl, Map<String, ?> params){ Iterator<String> ...

  8. Java入门第一季——从此投身Java??

    找工作告一段落. 最后的工作呢,和java紧密相关,也是阴差阳错,不过都是软件开发,都好了,不过以后侧重点肯定是在java这边,php有机会还是一直学下去的,那么美的说~ Java开发第一季  一.简 ...

  9. 深入jar包:从jar包中读取资源文件

    我们常常在代码中读取一些资源文件(比如图片,音乐,文本等等).在单独运行的时候这些简单的处理当然不会有问题.但是,如果我们把代码打成一个jar包以后,即使将资源文件一并打包,这些东西也找不出来了.看看 ...

  10. sqlserver 分组 group by

    select 名称, COUNT(名称) as 数量之和from 信息group by all 名称