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个力气, ...
随机推荐
- js文件加载太慢,JavaScript文件加载加速
原文出自:https://blog.csdn.net/seesun2012 js脚本加载太慢,JavaScript脚本加载加速(亲测有效) 测试背景: JS文件大小:6.1kB 传统形式加载js文件: ...
- [javaSE] IO流(对象序列化)
写入 获取ObjectOutputStream对象,new出来,构造参数:FileOutputStream对象目标文件 调用ObjectOutputStream对象的writeObject()方法,参 ...
- 十九、异步任务编排CompletableFuture
一.简介 并发编程中我们经常创建异步线程来执行任务.但是,当异步任务之间存在依赖关系时,使得我们开发过程变得更加复杂.比如: 1.线程2依赖于线程1的执行结果 2.线程3依赖于线程1和线程2执行结果的 ...
- bnu 10783 格斗游戏 线段与圆的关系
格斗游戏 Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld Java class name: ...
- Lucene原理之概念
概念: 数据分两种: 1.结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等. 2.非结构化数据:指不定长或无固定格式的数据,如邮件,word文档等.(半结构化数据:如XML,HTML等, ...
- 洛谷P4717 【模板】快速沃尔什变换(FWT)
题意 题目链接 Sol 背板子背板子 #include<bits/stdc++.h> using namespace std; const int MAXN = (1 << 1 ...
- QQ 聊天机器人小薇 2.1.0 发布!
本次发布加入了支持茉莉机器人,并且更容易搭建开发环境,在线显示登录二维码~ 简介 XiaoV(小薇)是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动: 监听多个 QQ 群消息 ...
- numpy数组属性查看及断言
numpy数组属性查看:类型.尺寸.形状.维度 import numpy as np a1 = np.array([1,2,3,4],dtype=np.complex128) print(a1) ...
- springmvc中Controller前端控制器的映射与返回数据,以及异常处理
.@RequestMapping映射 该注解中存的是映射路径的字符串 1.1 value的值是一个数组,也就是说可以定义多个访问路径,同时“.action”可以省略,前端控制器中主要查找主体部分.注意 ...
- flask框架下的jinja2模板引擎(2)(过滤器与自定义过滤器)
flask框架下的jinja2模块引擎(1):https://www.cnblogs.com/chichung/p/9774556.html 这篇论文主要用来记录下 jinja2 的过滤器. 什么是过 ...