题意:

  给一个h*w的矩阵,每个格子中是'#'和'.'两个符号之一,分别代表草和洞。现在要将洞给围起来(将草和洞分离),每条边需花费b元(即将一个洞包起来需要4边,将2个连续的洞包起来需要6边,省了2条边)。有个特殊能力,能将洞变成草,花费f。当然也能将草变成洞,花费d。围起洞来需要多少花费。矩阵四周最边边的格子都必须是草,即出现洞就必须转草。

  转换:洞--->草--->洞

          f     d     (元/格)

  围洞: b元/边。

思路:

  如果能够尽量让洞都靠在一起,那肯定是最小花费,因为少了很多条边。但是转换并不是免费,如果太贵,还不如不转,直接围。

  这很像用一条绳子将洞给围起来,然后量绳子的周长。如果将格子看成点,那么就很像一个'割'(即将点分成两个集合)。问题是如何建模?

  可以这么想,假设草上面都是水,自然就会流进洞里面,那么相邻的如果是草跟洞,则这条边就会有流通过,容量最多是b(相当于绳子的一部分)。这样子每个相邻的格子都需要建2条边互指(当然需要反向边),容量都是b,使得水可以流向洞中,花费就是流量。如果此时跑一次最大流(得加源汇点),就相当于求出不作'草洞'转换的围洞花费了。

  但是问题是可以转来转去,如果草转洞很便宜,则应多转成洞。这样就需要协调了。水往低处流。我们在源点S到所有边边的草格子建立1条边,容量INF,接着,S连到所有其他的草格子,容量为d。其他的洞格子连到汇点T,容量为f。还有,每个格子和相邻的格子都有2条边,容量是b。新图就建完了,但是为什么这么做?

  如下图,9个格子,4个草格子(边边被去掉):

  . . .

  .#.

  ###

  明显,d比较小时,红色那块应该转洞,3段变1段花费。多小合适?d+b<3b时就合适,因为转的费用d,加上流进该新洞的流b,比原来需要3b要少。我们所设的(S-红草)这条边的容量是d,当满流时,也会从'红草'流向3个方向的洞中去,由红草流出的最大流不超过3b。此时,红草下的黑草,设为黑草A,它最多有b的流量可以流到红草喔,但是没办法,红草能承担的上限也只能是3b。若(S-红草)的流量>0,相当于帮忙减小了红草的压力,红草此时只是承受了来自S的d流量,还有黑草A的流量b而已。这样流来流去,红草流出的上限为3b,但是如果S给红草的d太小,即使加上黑草A的b,也是到达不了上限3b的,那么自动就被限流了。这个模型自动就被限流了,好像自动帮我们选择了“最省钱的方式”。同理,(洞-T) 也是这样,流到草格子B的流量欲超过f的话,还不如直接转成草,限流f就相当于自动转成草,如果少于f则相当于不转。

 #include <bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define INF 0x7f7f7f7f
using namespace std;
const int N=;
char g[][];
vector<int> vect[N];
struct node
{
int from, to, cap, flow;
node(){};
node(int a,int b,int c,int d):from(a), to(b), cap(c), flow(d){};
}edge[N*]; int edge_cnt;
void add_node(int a,int b,int c,int d)
{
edge[edge_cnt]=node(a,b,c,d);
vect[a].push_back(edge_cnt++);
} bool isOk(int x,int y,int h,int w){return x>&&x<=h&&y>&&y<=w? : ;}//判断是否在矩阵内 void build_graph(int h, int w,int b, int d,int f)//建图。
{
for(int i=; i<=h; i++)
{
for(int j=; j<=w; j++)
{
if( isOk(i, j-, h, w) ) //左边
{
add_node((i-)*w+j-, (i-)*w+j, b, );
add_node((i-)*w+j, (i-)*w+j-, , );
}
if( isOk(i, j+ ,h, w) ) //右边
{
add_node((i-)*w+j+, (i-)*w+j, b, );
add_node((i-)*w+j, (i-)*w+j+, , );
}
if( isOk(i-, j, h, w) ) //上边
{
add_node((i-)*w+j, (i-)*w+j, b, );
add_node((i-)*w+j, (i-)*w+j, , );
}
if( isOk(i+,j, h, w) ) //下边
{
add_node((i-)*w+j, i*w+j, b, );
add_node(i*w+j, (i-)*w+j, , );
} }
} for(int i=; i<=h; i++)
{
for(int j=; j<=w; j++)
{
if(i==||i==h || j==||j==w) //边边的草
{
add_node(, (i-)*w+j, INF, );
add_node((i-)*w+j, , , );
}
else if(g[i][j]=='#') //源点-草
{
add_node(, (i-)*w+j, d, );
add_node((i-)*w+j, , , );
}
else //洞-汇点
{
add_node((i-)*w+j, w*h+, f, );
add_node(w*h+, (i-)*w+j, , );
}
}
}
} int flow[N], path[N]; int BFS(int s,int e)
{
deque<int> que(,s);
flow[s]=INF;
while(!que.empty())
{
int x=que.front();
que.pop_front();
for(int i=; i<vect[x].size(); i++)
{
node e=edge[vect[x][i]];
if(!flow[e.to]&&e.cap>e.flow)
{
path[e.to]=vect[x][i];
flow[e.to]=min(flow[e.from], e.cap-e.flow);
que.push_back(e.to);
}
}
if(flow[e]) break;;
}
return flow[e];
} int max_flow(int s,int e)
{
int ans_flow=;
while(true)
{
memset(flow,,sizeof(flow));
memset(path,,sizeof(path)); int tmp=BFS(s, e);
if(tmp==) return ans_flow;
ans_flow+=tmp; int ed=e;
while(ed!=s)
{
int t=path[ed];
edge[t].flow+=tmp;
edge[t^].flow-=tmp;
ed=edge[t].from;
}
}
} int main()
{
freopen("input.txt", "r", stdin);
int t, w, h, d, f, b;
char c;
cin>>t;
while(t--)
{
scanf("%d%d %d%d%d", &w, &h, &d, &f,&b);
edge_cnt=;
memset(edge,,sizeof(edge));
for(int i=N-; i>=; i--) vect[i].clear(); for(int i=; i<=h; i++)
{
for(int j=; j<=w; j++)
{
c=getchar();
if(c=='#'||c=='.') g[i][j]=c;
else j--;
}
}
int ans=;
//处理掉四周:洞转草花费f元/格
for(int i=; i<=w; i++) if(g[][i]!='#') ans+=f; //第一行
for(int i=; i<=w; i++) if(g[h][i]!='#') ans+=f; //最后一行
for(int i=; i<h; i++) if(g[i][]!='#') ans+=f;
for(int i=; i<h; i++) if(g[i][w]!='#') ans+=f;
build_graph(h, w, b, d, f);
printf("%d\n",max_flow(, w*h+)+ans);
}
return ;
}

AC代码

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. Uva -1515 Pool construction(最小割)

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

  4. UVa1515 Pool construction(最小割)

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

  5. poj--1149--PIGS(最大流经典建图)

    PIGS Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %I64d & %I64u Submit Status D ...

  6. UVa 1515 (最小割) Pool construction

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

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

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

  8. [网络流最大流经典][uva 11082][矩阵解压]

    题目大意 分析 #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring ...

  9. UVA 10720 Graph Construction 贪心+优先队列

    题目链接: 题目 Graph Construction Time limit: 3.000 seconds 问题描述 Graph is a collection of edges E and vert ...

随机推荐

  1. Spark Streaming揭秘 Day27 Job产生机制

    Spark Streaming揭秘 Day27 Job产生机制 今天主要讨论一个问题,就是除了DStream action以外,还有什么地方可以产生Job,这会有助于了解Spark Streaming ...

  2. Spark Streaming揭秘 Day12 数据安全容错(Executor篇)

    Spark Streaming揭秘 Day12 数据安全容错(Executor篇) 今天,让我们研究下SparkStreaming在Executor端的数据安全及容错机制. 在SparkStreami ...

  3. (转)Qt Model/View 学习笔记 (三)——Model类

    Model类 基本概念 在model/view构架中,model为view和delegates使用数据提供了标准接口.在Qt中,标准接口QAbstractItemModel类中被定义.不管数据在底层以 ...

  4. 【学习总结】OS X , IOS , IOS SDK , XCode之间的关系

    几个基本的概念 : OS X : 属于桌面PC级别(IMac,MacPro等)对应安装的操作系统 IOS : 属于移动设备级别(Iphone,Ipad等)对应安装的操作系统 XCode: 是一个IDE ...

  5. C# Windows - Button 控件

    .Net Framework提供了一个派生于Control的类System.Windows.Forms.ButtonBase,它实现了Button控件所需的基本功能. System.Windows.F ...

  6. [Windows Azure] Querying Tables and Entities

    Constructing Filter Strings When constructing a filter string, keep these rules in mind: Use the log ...

  7. 5.2:缓存中获取单例bean

    5.2  缓存中获取单例bean 介绍过FactoryBean的用法后,我们就可以了解bean加载的过程了.前面已经提到过,单例在Spring的同一个容器内只会被创建一次,后续再获取bean直接从单例 ...

  8. [转载]js 遍历数组对象

    有一个JSON数组如下 all = {"error":0,"content":[{"name":"北京","v ...

  9. PAT-乙级-1018. 锤子剪刀布 (20)

    1018. 锤子剪刀布 (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 大家应该都会玩“锤子剪刀布”的游 ...

  10. Visual C++ 6.0静态、动态链接库

    1.什么是静态连接库,什么是动态链接库          静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了 ...