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

这道题要求一种填充+挖坑+建屏障的方法,使得这块土地上的所有坑和草地之间都有屏障,挖坑花费d每块,填充花费f每块,建屏障花费b每两块之间,注意并不要求一定有坑,但是外围一圈要一定没有坑,所以需要预先填充好

令st代表平地,ed代表坑,边权为花费,那么本题是要求一个st-ed最小割,因为s到平地花费为0,所以不建边,同理坑到ed也不需要花费不建边,每个点到相邻点建边,容量为b,s到坑建边,容量为d,平地到e建边,容量为f,为了防止外围的平地被挖,容量设为inf.

以st为起点,ed为终点,求一遍最大流,即最小割即可
这道题一开始会以为是dp,其实是一道最小割,虽然有2500个点,50000条边左右,但是仍然可以用网络流跑过,一开始想不出怎么处理屏障,但是其实只需要把每个点和相邻点之间都连起来即可,横向的流量没有意义,也就是说只有平地和坑之间的边会限制流量.

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=5000;
const int maxm=5000000;
const int inf=0x3fffffff;
int first[maxn];
struct edge{
int nxt,from,t,f,c;
}e[maxm];
int w,h,d,fl,b,len;
char maz[60][60];
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int st,ed,num; int dis[maxn],gap[maxn];
bool in(int x,int y){return x>=0&&x<h&&y>=0&&y<w;}
void addedge(int from,int t,int c){
e[len].nxt=first[from];
e[len].from=from;
e[len].t=t;
e[len].f=c;
e[len].c=c;
first[from]=len++;
swap(from,t);c=0; e[len].nxt=first[from];
e[len].from=from;
e[len].t=t;
e[len].f=c;
e[len].c=c;
first[from]=len++;
}
int dfs(int s,int flow){
if(s==ed)return flow;
int mindis=num-1;
int tflow=flow,sub;
for(int p=first[s];p!=-1;p=e[p].nxt){
int t=e[p].t;
if(e[p].f>0){
if(dis[t]+1==dis[s]){
sub=dfs(t,min(tflow,e[p].f));
e[p].f-=sub;e[p^1].f+=sub;
tflow-=sub;
if(dis[st]>=ed)return flow-tflow;
if(tflow<=0)break;
}
mindis=min(mindis,dis[t]);
}
}
if(flow-tflow<=0){
--gap[dis[s]];
if(gap[dis[s]]==0)dis[st]=ed;
else {
dis[s]=mindis+1;
++gap[dis[s]];
}
}
return flow-tflow;
} int maxflow(){
int flow=0;
gap[0]=num;
while(dis[st]<ed){
flow+=dfs(st,inf);
}
return flow;
}
void init(){
len=0;
st=w*h;
ed=st+1;
num=st+2;
fill(first,first+num,-1);
fill(gap,gap+num,0);
fill(dis,dis+num,0);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d%d%d",&w,&h,&d,&fl,&b);
init();
int ans=0;
for(int i=0;i<h;i++)scanf("%s",maz[i]); for(int i=0;i<h;i++){
for(int j=0;j<w;j++){
for(int k=0;k<4;k++){
int tx=i+dx[k],ty=j+dy[k];
if(in(tx,ty)){
addedge(i*w+j,tx*w+ty,b);
}
}
if(maz[i][j]=='#'){
if(i==0||i==h-1||j==0||j==w-1){
addedge(i*w+j,ed,inf);
}
else {
addedge(i*w+j,ed,d);
}
}
else {
if(i==0||i==h-1||j==0||j==w-1){
ans+=fl;
maz[i][j]='#';
addedge(i*w+j,ed,inf);
}
else {
addedge(st,i*w+j,fl);
}
}
}
}
ans+=maxflow();
printf("%d\n",ans);
}
return 0;
}

  

UVALive 5905 Pool Construction 最小割,s-t割性质 难度:3的更多相关文章

  1. uvalive 5905 Pool construction

    题目链接 题意: 有一个花园,有些地方是草地,有些地方是洞,现在要在这个花园中修建一个泳池,泳池全部由洞构成. 把洞变成草地需要花费一定的费用,把草地变成洞也需要花费一定的费用,并且泳池的边缘的草地上 ...

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

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

  3. UVa1515 Pool construction(最小割)

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

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

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

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

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

  6. 训练指南 UVALive - 3126(DAG最小路径覆盖)

    layout: post title: 训练指南 UVALive - 3126(DAG最小路径覆盖) author: "luowentaoaa" catalog: true mat ...

  7. UVa 1515 (最小割) Pool construction

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

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

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

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

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

随机推荐

  1. JavaWeb学习总结(十三)--数据库连接池

    一.数据库连接池的概念 用池来管理Connection,这可以重复使用Connection.有了池,所以我们就不用自己来创建Connection,而是通过池来获取Connection对象.当使用完Co ...

  2. Hbase之必要时取出请求的行(列族所有数据)

    import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.CellScanner; import org. ...

  3. python and java

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:kula链接:http://www.zhihu.com/question/29690505/answer/67149864来源 ...

  4. C++从键盘输入文件结束符

            当我们使用一个istream对象作为条件时,其效果是检测流的状态.如果流是有效的,即流未遇到错误,那么检测成功.当遇到文件结束符,或遇到一个无效输入时(例如需要将输入读到一个int变量 ...

  5. sessionStorage

    for(i=0;i<tkt.length;i++){ if(tkt[i].redEnvelopeType==1){ full1+="<div class='pic_01' id= ...

  6. 双日历插件--jq datepicker时间范围选择

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  7. python 练习 17

    #!/usr/bin/python # -*- coding: UTF-8 -*- f1 = 1 f2 = 1 for i in range(1,21): print '%12d %12d' % (f ...

  8. [saiku] 简化/汉化/设置默认页

    上一篇分析了schema文件 [ http://www.cnblogs.com/avivaye/p/4877832.html] 在安装完毕Saiku后,由于是社区版本,所以界面上存在很多升级为商业版的 ...

  9. 笔记6:winfrom连接sql server 进行数据交换

    今天的作业是用winfrom窗体做一个留言板,如图: 要求和数据库有查询和添加功能.下拉框里的值是直接获取数据库中的值 一.连接数据库,获取表中数据 //创建一个存数据的表 DataTable tab ...

  10. Uva---10881 Piotr's Ants(蚂蚁)

    Problem DPiotr's AntsTime Limit: 2 seconds "One thing is for certain: there is no stopping them ...