题意:

输入一个字符矩阵,'.'代表洞,'#'代表草地。可以把草改成洞花费为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. asp.net中XmlDocument解析出现出错,处理特殊字符

    xml结构会解析一些特殊字符,特别是& <  所以我们需要把结构放在CDATA中处理,CDATA里面的内容在XmlDocument 解析时会自动忽略掉,不会解析里面的内容:因此,我这里就 ...

  2. 模仿易信的UI

    易信,它的UI还是很简洁,因此本人想模仿一下它,用了一天的时候来研究它的资源文件,终于被我写出来.先看下效果图吧.     (一)首页的标题     main_title.xml <?xml v ...

  3. Zabbix实现告警分级

    Zabbix中trigger的severity的值定义了trigger的不同严重程度,其中severity默认的6个值为 Not classified, Information, Warning, A ...

  4. apache nginx php不显示版本号

    apache 不显示版本号 http.conf 中的 修改为 ServerTokens ProdServerSignature Off 有的版本没有,在最后添加即可 php php.ini 中的 修改 ...

  5. 解决Ubuntu开机自动挂载硬盘回收站不可用等权限问题

    1.修改fstab sudo gedit /etc/fstab 2.添加如下代码 #Entry for /dev/sdb7 : UUID=78A675EB46D703C4 /media/anseey/ ...

  6. OWASP

    开放式Web应用程序安全项目(OWASP,Open Web Application Security Project)是一个组织,它提供有关计算机和互联网应用程序的公正.实际.有成本效益的信息.其目的 ...

  7. spoj 78

    数学  组合 隔板法 #include <iostream> #include <cstring> #include <cstdio> #include <s ...

  8. UVA 10246 Asterix and Obelix

    题意:每个城市举办庆祝有一定的花费,A在路径上会选择庆祝花费最大的城市 让你求,A回家所花的路费和庆祝费最少,也就是说并不是最短路径就是结果, 还有可能就是路费比最短路径的多,但是庆祝费就比它的少,总 ...

  9. qsort()与besearch()

    功 能: 使用快速排序例程进行排序 头文件:stdlib.h 用 法: void qsort(void *base,int nelem,int width,int (*fcmp)(const void ...

  10. 深入理解JVM—字节码执行引擎

    原文地址:http://yhjhappy234.blog.163.com/blog/static/3163283220122204355694/ 前面我们不止一次的提到,Java是一种跨平台的语言,为 ...