题意:

输入一个字符矩阵,'.'代表洞,'#'代表草地。可以把草改成洞花费为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. 玩转SmartQQ之登录

    SmartQQ是腾讯新出的一个WebQQ,登录地址是:http://w.qq.com/,目前之前的WebQQ可以继续使用,登录地址:http://web2.qq.com/webqq.html,Smar ...

  2. 被git extensions给坑了,Not owner 解决办法

    我只遇到这一种情况,不能访问git文件主库, 清空以前的历史文件,包括默认配置文件,重新安装一遍git extension,然后设置账号和密码, 在打开bash设置私钥和公钥 把公钥添加到你的git的 ...

  3. Codeforces Round #347 (Div. 2) C. International Olympiad 找规律

    题目链接: http://codeforces.com/contest/664/problem/C 题解: 这题最关键的规律在于一位的有1989-1998(9-8),两位的有1999-2098(99- ...

  4. div均匀分布代码实例

    多个div在同一行以相同间隔分布: 这样的布局效果使用非常的频繁,也就是让多个div在一行分布,并且div于div之间的间隙是一样的,多用在对于产品的展示之用,下面就介绍一下如何实现此中布局,代码实例 ...

  5. 【POJ】【3710】Christmas Game

    博弈论 贾志豪论文上的题目……题解请看论文 Orz了一下Hzwer Source Code Problem: User: sdfzyhy Memory: 716K Time: 0MS Language ...

  6. SQL Server 之 校对

    _CI(CS) 是否区分大小写,CI不区分,CS区分 _AI(AS) 是否区分重音,AI不区分,AS区分 _KI(KS) 是否区分假名类型,KI不区分,KS区分 _WI(WS) 是否区分宽度 WI不区 ...

  7. sigleSchool 存储过程例1

    CREATE OR REPLACE PROCEDURE SINGLSCHOOL( PICIID IN VARCHAR2, SCHOOLID IN NUMBER, SCHETYPE IN number, ...

  8. 【Unity3D】iOS 推送实现

    原地址:http://www.iappfan.com/%E3%80%90unity3d%E3%80%91ios-%E6%8E%A8%E9%80%81%E5%AE%9E%E7%8E%B0/ #impor ...

  9. lintcode : 平衡二叉树

    题目 平衡二叉树 给定一个二叉树,确定它是高度平衡的.对于这个问题,一棵高度平衡的二叉树的定义是:一棵二叉树中每个节点的两个子树的深度相差不会超过1. 样例 给出二叉树 A={3,9,20,#,#,1 ...

  10. HttpServletRequestWrapper的使用

    老大给了一个很实际的需求:有段程序,使用Http的方式与合作商交互,而且是明文传输数据.我方的代码已经打包放在服务器上运行了很长时间,这时合作商突然要求修改数据传输的方式,要求加密后再传输,而我方的原 ...