题意:

输入一个字符矩阵,'.'代表洞,'#'代表草地。可以把草改成洞花费为d,或者把洞改成草花费为f,最后还要在草和洞之间修围栏花费为b。

但要保证最外一圈是草,求最小费用。

分析:

还不是特别理解紫书上的讲解。。

首先把最外一圈的洞变成草,并累加花费。

增加一个源点和一个汇点,源点连接每个草地,汇点连接每个洞。

源点与最外一圈的草地连一条容量无穷大的边,与其他草地连一条容量为d的边。表示把这条弧切断,割的容量增加d,草就会变成洞。

每个洞与汇点连一条容量为f的边。

相邻两个格子之间连一条双向边。

用最大流算法求最小割在加上之前把边界上的洞变成草的费用,就是最小花费。

 #include <bits/stdc++.h>

 using namespace std;

 const int maxn =  *  + ;
const int INF = ; struct Edge
{
int from, to, cap, flow;
}; bool operator < (const Edge& a, const Edge& b)
{ return a.from < b.from || ( a.from == b.from && a.to < b.to ); } struct Dinic
{
int n, m, s, t;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn]; //BFS
int d[maxn]; //起点到i的距离
int cur[maxn]; //当前弧指针 int Init(int n)
{
for(int i = ; i < n; ++i) G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int cap)
{
edges.push_back(Edge{from, to, cap, });
edges.push_back(Edge{to, from, , });
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} bool BFS()
{
memset(vis, false, sizeof(vis));
queue<int> Q;
Q.push(s);
vis[s] = true;
d[s] = ;
while(!Q.empty())
{
int x = Q.front(); Q.pop();
for(int i = ; i < G[x].size(); ++i)
{
Edge& e = edges[G[x][i]];
if(!vis[e.to] && e.cap > e.flow)
{
vis[e.to] = true;
d[e.to] = d[x] + ;
Q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x, int a)
{
if(x == t || a == ) return a;
int flow = , f;
for(int& i = cur[x]; i < G[x].size(); ++i)
{
Edge& e = edges[G[x][i]];
if(d[x] + ==d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > )
{
e.flow += f;
edges[G[x][i]^].flow -= f;
flow += f;
a -= f;
if(a == ) break;
}
}
return flow;
} int MaxFlow(int s, int t)
{
this->s = s; this->t = t;
int flow = ;
while(BFS())
{
memset(cur, , sizeof(cur));
flow += DFS(s, INF);
}
return flow;
}
}g; int w, h;
char pool[][]; inline int ID(int i, int j) { return i*w+j; } int main()
{
//freopen("in.txt", "r", stdin); int T, d, f, b;
scanf("%d", &T);
while(T--)
{
scanf("%d%d%d%d%d", &w, &h, &d, &f, &b);
for(int i = ; i < h; ++i) scanf("%s", pool[i]);
int cost = ;
for(int i = ; i < h; ++i)//把边上的洞填成草
{
if(pool[i][] == '.') { pool[i][] = '#'; cost += f; }
if(pool[i][w-] == '.') { pool[i][w-] = '#'; cost += f; }
}
for(int i = ; i < w; ++i)
{
if(pool[][i] == '.') { pool[][i] = '#'; cost += f; }
if(pool[h-][i] == '.') { pool[h-][i] = '#'; cost += f; }
} g.Init(h*w+);
for(int i = ; i < h; i++)
for(int j = ; j < w; j++)
{
if(pool[i][j] == '#')
{
int cap = d;
if(i == || i == h- || j == || j == w-) cap = INF;
g.AddEdge(w*h, ID(i, j), cap);
}
else
{
g.AddEdge(ID(i, j), w*h+, f);
}
if(i > ) g.AddEdge(ID(i, j), ID(i-, j), b);
if(i < h-) g.AddEdge(ID(i, j), ID(i+, j), b);
if(j > ) g.AddEdge(ID(i, j), ID(i, j-), b);
if(j < w-) g.AddEdge(ID(i, j), ID(i, j+), b);
} printf("%d\n", cost + g.MaxFlow(w*h, w*h+));
} return ;
}

代码君

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

  1. uva 11248 最小割

    Dinic 1 #include<iostream> #include<string> #include<algorithm> #include<cstdli ...

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

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

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

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

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

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

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

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

  6. UVa1515 Pool construction(最小割)

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

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

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

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

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

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

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

随机推荐

  1. JS实现刷新iframe的方法

    <iframe src="1.htm" name="ifrmname" id="ifrmid"></iframe> ...

  2. android studio 不能在线更新android SDK Manager问题解决办法

    Failed to fetch URL https://dl-ssl.google.com/android/repository/addons_list-2.xml, reason: Connecti ...

  3. python 日期转星期

    import time import datetime today = int(time.strftime('%w')) print today anyday = datetime.datetime( ...

  4. UVA 11858 Frosh Week 逆序对统计

    题目链接: http://acm.hust.edu.cn/vjudge/contest/122094#problem/H Frosh Week Time Limit:8000MSMemory Limi ...

  5. display:none和visibility: hidden二三事

    display:none属性后,HTML元素(对象)的宽度.高度等各种属性值都将“丢失”;而使用visibility:hidden属性后,HTML元素(对象)仅仅是在视觉上看不见(完全透明),而它所占 ...

  6. 以“图片渐入渐出”为例讲述jQuery插件的具体实现

    首先声明,此代码以网友“斯迈欧”原创作为此例的讲解: 在这之前我们先看看我们要做的效果是什么样的: 解析下面的样式:我们要图片在过“一定时间”后自动切换,在右下角处有小方块似数字1,2,3,4,这些数 ...

  7. Guava文档翻译之 Guava简介

    用户指南 User Guide Guava项目包括了一些Google的核心库,是我们在基于Java的项目中所依赖的,这些库包括:集合,缓存,对基本类型的支持,并发库,通用的注解,字符串处理,I/O,等 ...

  8. /bin/bash^M: bad interpreter: No such file or dire

    在执行shell脚本时提示这样的错误主要是由于shell脚本文件是dos格式,即每一行结尾以\r\n来标识,而unix格式的文件行尾则以\n来标识.  查看脚本文件是dos格式还是unix格式的几种办 ...

  9. hdu 4578 Transformation 线段树

    没什么说的裸线段树,注意细节就好了!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> ...

  10. eclipse导入maven web 项目 但是不显示成web 项目

    http://blog.csdn.net/jun55xiu/article/details/9028403 1:导入Maven webapp项目(以extdirectspring-demo为例): i ...