UVa 1515 - Pool construction(最小割)
链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4261
题意:
输入一个h行w列的字符矩阵,草地用“#”表示,洞用“.”表示。
你可以把草改成洞,每格花费为d,也可以把洞填上草,每格花费为f。
最后还需要在草和洞之间修围栏,每条边的花费为b。
整个矩阵第一行/列和最后一行/列必须都是草。
求最小花费。2≤w,h≤50,1≤d, f, b≤10000。
分析:
围栏的作用是把草和洞隔开,让人联想到了“割”这个概念。
可是“割”只是把图中的结点分成了两个部分,而本题中,草和洞都能有多个连通块。怎么办呢?
添加源点S和汇点T,与其他点相连,则所有本不连通的草地/洞就能通过源点和汇点间接连起来了。
由于草和洞可以相互转换,而且转换还需要费用,所以需要一并在“割”中体现出来。
为此,规定与S连通的都是草,与T连通的都是洞,
则S需要往所有草格子连一条容量为d的边,表示必须把这条弧切断(割的容量增加d),
这个格子才能“叛逃”到T的“阵营”,成为洞。
由于题目说明了最外圈的草不能改成洞,从S到这些草格子的边容量应为正无穷
(在这之前需要把边界上的所有洞填成草,累加出这一步所需的费用)。
同理,所有不在边界上的洞格子往T连一条弧,费用为f,
表示必须把这条弧切断(割的容量增加f),才能让这个洞变成草。
相邻两个格子u和v之间需要连两条边u->v和v->u,容量均为b,
表示如果u是草,v是洞,则需要切断弧u->v;如果v是草,u是洞,则需要切断弧v->u。
这样,用最大流算法求出最小割,就可以得到本题的最小花费。
代码:
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std; /// 结点下标从0开始,注意maxn
struct Dinic {
static const int maxn = * + ;
static const int INF = 0x3f3f3f3f;
struct Edge {
int from, to, cap, flow;
}; int n, m, s, t; // 结点数,边数(包括反向弧),源点编号和汇点编号
vector<Edge> edges; // 边表。edges[e]和edges[e^1]互为反向弧
vector<int> G[maxn]; // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号
bool vis[maxn]; // BFS使用
int d[maxn]; // 从起点到i的距离
int cur[maxn]; // 当前弧下标 void init(int n) {
this->n = n;
edges.clear();
for(int i = ; i < n; i++) G[i].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, , sizeof(vis));
queue<int> Q;
Q.push(s);
vis[s] = ;
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] = ;
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;
}
vector<int> Mincut() { // 在Maxflow之后调用
vector<int> ans;
for(int i = ; i < edges.size(); i++) {
Edge& e = edges[i];
if(vis[e.from] && !vis[e.to] && e.cap > ) ans.push_back(i);
}
return ans;
}
} dc; const int INF = 0x3f3f3f3f;
const int UP = + ;
int r, c;
char site[UP][UP];
inline int id(int rr, int cc) { return rr*c+cc; } int main() {
int T, d, f, b;
scanf("%d", &T);
while(T--) {
scanf("%d%d%d%d%d", &c, &r, &d, &f, &b);
for(int i = ; i < r; i++) scanf("%s", site[i]);
int ans = ;
for(int i = ; i < r; i++) {
if(site[i][] == '.') site[i][] = '#', ans += f;
if(site[i][c-] == '.') site[i][c-] = '#', ans += f;
}
for(int i = ; i < c; i++) {
if(site[][i] == '.') site[][i] = '#', ans += f;
if(site[r-][i] == '.') site[r-][i] = '#', ans += f;
} dc.init(r*c+);
int start = r*c, finish = r*c+;
for(int rr = ; rr < r; rr++) {
for(int cc = ; cc < c; cc++) {
if(site[rr][cc] == '#') {
int cap = (rr== || rr==r- || cc== || cc==c-) ? INF : d;
dc.AddEdge(start, id(rr,cc), cap);
} else dc.AddEdge(id(rr,cc), finish, f);
if(rr > ) dc.AddEdge(id(rr,cc), id(rr-,cc), b);
if(rr < r-) dc.AddEdge(id(rr,cc), id(rr+,cc), b);
if(cc > ) dc.AddEdge(id(rr,cc), id(rr,cc-), b);
if(cc < c-) dc.AddEdge(id(rr,cc), id(rr,cc+), b);
}
}
printf("%d\n", ans + dc.Maxflow(start, finish));
}
return ;
}
UVa 1515 - Pool construction(最小割)的更多相关文章
- Uva -1515 Pool construction(最小割)
输入一个字符矩阵,'.'代表洞,'#'代表草地.可以把草改成洞花费为d,或者把洞改成草花费为f,最后还要在草和洞之间修围栏花费为b. 首先把最外一圈的洞变成草,并累加花费. 增加一个源点和一个汇点,源 ...
- UVA 1515 Pool construction 最大流跑最小割
Pool construction You are working for the International Company for Pool Construction, a constructio ...
- UVALive 5905 Pool Construction 最小割,s-t割性质 难度:3
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- UVA 1515 Pool construction 水塘(最大流,经典)
题意: 给一个h*w的矩阵,每个格子中是'#'和'.'两个符号之一,分别代表草和洞.现在要将洞给围起来(将草和洞分离),每条边需花费b元(即将一个洞包起来需要4边,将2个连续的洞包起来需要6边,省了2 ...
- UVA - 10480 Sabotage【最小割最大流定理】
题意: 把一个图分成两部分,要把点1和点2分开.隔断每条边都有一个花费,求最小花费的情况下,应该切断那些边.这题很明显是最小割,也就是最大流.把1当成源点,2当成汇点,问题是要求最小割应该隔断那条边. ...
- UVa 1515 (最小割) Pool construction
题意: 输入一个字符矩阵,'.'代表洞,'#'代表草地.可以把草改成洞花费为d,或者把洞改成草花费为f,最后还要在草和洞之间修围栏花费为b. 但要保证最外一圈是草,求最小费用. 分析: 还不是特别理解 ...
- 【uva 1515】Pool construction(图论--网络流最小割 模型题)
题意:有一个水塘,要求把它用围栏围起来,每个费用为b.其中,(#)代表草,(.)代表洞,把一个草变成洞需要费用d, 把一个洞变成草需要费用f.请输出合法方案中的最小费用. 解法:(不好理解...... ...
- UVa1515 Pool construction(最小割)
题目 Source https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...
- UVA-1515 Pool construction (最小割)
题目大意:有一块地,分成nxm块.有的块上长着草,有的块上是荒地.将任何一块长着草的块上的草拔掉都需要花费d个力气,往任何一块荒地上种上草都需要花费f个力气,在草和荒地之间架一个篱笆需要花费b个力气, ...
随机推荐
- linux运维工程师成长过程
原文地址:https://blog.csdn.net/kwame211/article/details/78059331 初级篇 linux运维人员常用工具拓扑详见: 1rsync工具 很多地方经常会 ...
- C#构建树形数据结构
转自:https://www.jb51.net/article/125747.htm 树形结构:最近在做任务管理,任务可以无限派生子任务且没有数量限制,前端采用Easyui的Treegrid树形展示控 ...
- 十、获取异步线程返回值Callable
一.简介 异步线程的实现接口Runnable是无法获得返回结果的,而另一个接口Callable可以返回结果.并通过如Future等方式来获取异步结果. 二.代码示例 import java.util. ...
- java四则运算----前缀、中缀、后缀表达式
接到一个新需求,需要实现可配置公式,然后按公式实现四则运算. 刚拿到需求,第一反应就是用正则匹配‘(’,‘)’,‘+’,‘-’,‘*’,‘/’,来实现四则运算,感觉不复杂. 然后开始coding.发现 ...
- 06-码蚁JavaWeb之Servlet生命周期与基本配置
学习地址:[撩课-JavaWeb系列1之基础语法-前端基础][撩课-JavaWeb系列2之XML][撩课-JavaWeb系列3之MySQL][撩课-JavaWeb系列4之JDBC][撩课-JavaWe ...
- [LeetCode] Three Sum题解
Three Sum: Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? ...
- visualvm 插件 visual gc 使用介绍
visual gc 是 visualvm 中的图形化查看 gc 状况的插件. 具体详细介绍可参照: http://www.oracle.com/technetwork/java/visualgc-13 ...
- Guava限流工具RateLimiter使用
公司最近在推一个限流工具接入,提供的功能有单机限流.集群限流等.想了解一下限流的原理和设计,看了一下wiki里面有提到用了guava的ratelimiter工具,查了一些资料了解了一下 主要的限流算法 ...
- hadoop start-all.sh报错JAVA_HOME is not set and could not be found.
原文 错误:JAVA_HOME is not set and could not be found,可能是因为JAVA_HOME环境没配置正确,还有一种情况是即使各结点都正确地配置了JAVA_HOME ...
- php中怎么导入自己写的类
如果写的类是写在当前php文件内,就直接实例化若你的类写在其他的php文件里,就要先用include或require,将类文件引入<?php include("class.php&qu ...