UVa 1515 (最小割) Pool construction
题意:
输入一个字符矩阵,'.'代表洞,'#'代表草地。可以把草改成洞花费为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的更多相关文章
- uva 11248 最小割
Dinic 1 #include<iostream> #include<string> #include<algorithm> #include<cstdli ...
- UVA 1515 Pool construction 最大流跑最小割
Pool construction You are working for the International Company for Pool Construction, a constructio ...
- UVa 1515 - Pool construction(最小割)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- 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 ...
- 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 (最小割)
题目大意:有一块地,分成nxm块.有的块上长着草,有的块上是荒地.将任何一块长着草的块上的草拔掉都需要花费d个力气,往任何一块荒地上种上草都需要花费f个力气,在草和荒地之间架一个篱笆需要花费b个力气, ...
- UVA1515 Pool construction (最小割模型)
如果不允许转化'#'和'.'的话,那么可以直接在'#'和'.'之间连容量为b的边,把所有'#'和一个源点连接, 所有'.'和一个汇点连接,流量不限,那么割就是建围栏(分割'#'和'.')的花费. 问题 ...
随机推荐
- WPF 多线程处理(5)
WPF 多线程处理(1) WPF 多线程处理(2) WPF 多线程处理(3) WPF 多线程处理(4) WPF 多线程处理(5) WPF 多线程处理(6) 项目的目录: 以下是FileStroage的 ...
- emulatorarm.exe已停止工作
今天使用ADT 打开android模拟器突然发现模拟器报错,[emulatorarm.exe已停止工作],昨天还是好好的,不知道为什么,重建新的模拟器还是这样. 解决办法: 更改ram大小为 512M ...
- 【BZOJ】【3275】Numbers
网络流/最小割 Orz了Jiry_2神犇,蒟蒻网络流建模什么的完全不会啊T_T 按奇偶性来分组实在太巧妙了……然后相关的点之间连边表示只能选其一,来求最小割…… /****************** ...
- 【娱乐】高端小游戏Manufactoria
Manufactoria 是一款游戏.游戏中,一家生产机器人的工厂内部出了一 些问题,生产出来的机器人有很多不合格的.一个机器人可以用一个含有红色和 蓝色的颜色串来描述,只有颜色串符合某种规律的机器人 ...
- linux挂载windwos共享文件
mount -t cifs -o useaname=***,password=*** //172.16.82.32/test /mnt username,password分别为windows那边允许共 ...
- 循环队列实现(C++) Ring Buffer
循环队列:队列有着先入先出的特性.但是对于队列如果删除队头以后剩下的空间将不会被释放,又由于队列只能由队尾插入这就导致被删除部分的空间被浪费.解决这个问题就是循环队列.循环队列顾名思义就是将队列串起来 ...
- 01-08-01【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate中的三种状态
以下属于不明来源资料: 引入 在程序运行过程中使用对象的方式对数据库进行操作,这必然会产生一系列的持久化类的实例对象.这些对象可能是刚刚创建并准备存储的,也可能是从数据库中查询的,为了区分这些对象,根 ...
- Node.js 4.0.0:灵雀云和 OneAPM 的整合测试
关于 Node.js 4.0.0 稳定版刚刚推出,备受期待,迫不及待地想用它写点东西:此外,要把 Demo 放到 Internet 上得有一个公网 IP ,看到灵雀云挺不错的而且提供域名解析,简直业界 ...
- HDU 1540 / POJ 2892 Tunnel Warfare (单点更新,区间合并,求包含某点的最大连续个数)
题意:一条线上有n个点,D x是破坏这个点,Q x是表示查询x所在的最长的连续的点的个数,R是恢复上一次破坏的点. 思路:这题的关键是查询. 将被毁的村庄看成空位,当查询某个点的时候,如果我们知道它左 ...
- POJ 2080 Calendar(很水的模拟)
刚开始一直WA,才发现原来代码中两处减去年份.月份的天数的判断条件用的是>=,虽然最后考虑n=0要退回一天的情况,但还是WA.后来改成>的条件判断,省去了考虑n=0的麻烦,AC. 此题无非 ...