Gym101128F:Landscaping
题意
有一片h*w的草坪,要把每一行从左到右修剪一遍,每一列从上到下修剪一遍。每个草坪要么是高低要么是平地。割草机从高地到平地或者从平地到高地,需要花费a。也可以把平地变为高地或者把高地变为平地,花费为b。求出最小花费是多少。
分析
网络流,应该也不算网络流里的难题,建图还是比较好想的(虽然我不会)。
当时在场上瞎几把建图,最后还是没过
这场结束后问了一下二发学长,恍然大悟。
把草地分为两个集合S和T,平地为S集合,高地位T集合,然后用最少的花费将两个集合分开,那么就是最小割了。
从s(源点)向每个平地连一条容量为b的边,从每个高地向t(汇点)连一条容量为b的边。如果需要把平地变高地或者把高低变平地,就割这几条边就可以了。
每个小草坪都向左边和下面的小草坪连双向边。为什么是双向边?因为是按照每个小草地的性质分为的两大集合。也可以理解为有可能从平地开始,也有可能从高地开始。
然后跑dinic就可以惹~~
下面是代码~
其实没啥看的,建图很简单,dinic是网上的模板··雾
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std; #define N 5000
#define INF 2147483000 struct Edge
{
int from,to,cap,flow;
Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
}; struct Dinic
{
int n,m,s,t;//结点数,边数(包括反向弧),源点编号,汇点编号
vector<Edge>edges;//边表,dges[e]和dges[e^1]互为反向弧
vector<int>G[N];//邻接表,G[i][j]表示结点i的第j条边在e数组中的编号
bool vis[N]; //BFS的使用
int d[N]; //从起点到i的距离
int cur[N]; //当前弧下标 void addedge(int from,int to,int cap)
{
edges.push_back(Edge(from,to,cap,));
edges.push_back(Edge(to,from,,));
int 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);
d[s]=;
vis[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)//x表示当前结点,a表示目前为止的最小残量
{
if(x==t||a==)return a;//a等于0时及时退出,此时相当于断路了
int flow=,f;
for(int&i=cur[x];i<G[x].size();i++)//从上次考虑的弧开始,注意要使用引用,同时修改cur[x]
{
Edge&e=edges[G[x][i]];//e是一条边
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;//a等于0及时退出,当a!=0,说明当前节点还存在另一个曾广路分支。 }
}
return flow;
} int Maxflow(int s,int t)//主过程
{
this->s=s,this->t=t;
int flow=;
while(bfs())//不停地用bfs构造分层网络,然后用dfs沿着阻塞流增广
{
memset(cur,,sizeof(cur));
flow+=dfs(s,INF);
}
return flow;
}
}dinic;
int h,w,a,b;
char G[][];
const int dx[]={,,,-};
const int dy[]={,-,,};
int main(){
scanf("%d%d%d%d",&h,&w,&a,&b);
dinic.s=,dinic.t=h*w+; for(int i=;i<=h;i++){
for(int j=;j<=w;j++){
scanf(" %c",&G[i][j]);
if(G[i][j]=='.')
dinic.addedge(dinic.s,(i-)*w+j,b);
else
dinic.addedge((i-)*w+j,dinic.t,b);
}
}
for(int i=;i<=h;i++){
for(int j=;j<=w;j++){
int u=(i-)*w+j;
int v1=i*w+j;
int v2=(i-)*w+j+;
if(i<h){
dinic.addedge(u,v1,a);dinic.addedge(v1,u,a);
}
if(j<w){
dinic.addedge(u,v2,a);dinic.addedge(v2,u,a);
}
}
}
int ans=dinic.Maxflow(dinic.s,dinic.t);
cout<<ans;
return ;
}
Gym101128F:Landscaping的更多相关文章
- 【63测试20161111】【BFS】【DP】【字符串】
第一题: tractor 题目描述 农场上有N(1 <= N <= 50,000)堆草,放在不同的地点上.FJ有一辆拖拉机,也在农场上.拖拉机和草堆都表示为二维平面上的整数坐标,坐标值在1 ...
- java web 开发三剑客 -------电子书
Internet,人们通常称为因特网,是当今世界上覆盖面最大和应用最广泛的网络.根据英语构词法,Internet是Inter + net,Inter-作为前缀在英语中表示“在一起,交互”,由此可知In ...
- 所有selenium相关的库
通过爬虫 获取 官方文档库 如果想获取 相应的库 修改对应配置即可 代码如下 from urllib.parse import urljoin import requests from lxml im ...
- bzoj 4439: [Swerc2015]Landscaping -- 最小割
4439: [Swerc2015]Landscaping Time Limit: 2 Sec Memory Limit: 512 MB Description FJ有一块N*M的矩形田地,有两种地形 ...
- 转载:hdu 题目分类 (侵删)
转载:from http://blog.csdn.net/qq_28236309/article/details/47818349 基础题:1000.1001.1004.1005.1008.1012. ...
- 【BZOJ4439】[Swerc2015]Landscaping 最小割
[BZOJ4439][Swerc2015]Landscaping Description FJ有一块N*M的矩形田地,有两种地形高地(用‘#’表示)和低地(用‘.’表示) FJ需要对每一行田地从左到右 ...
- In-Memory:内存数据库
在逝去的2016后半年,由于项目需要支持数据的快速更新和多用户的高并发负载,我试水SQL Server 2016的In-Memory OLTP,创建内存数据库实现项目的负载需求,现在项目接近尾声,系统 ...
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- 【.net 深呼吸】细说CodeDom(8):分支与循环
有人会问,为啥 CodeDom 不会生成 switch 语句,为啥没生成 while 语句之类.要注意,CodeDom只关心代码逻辑,而不是语法,语法是给写代码的人用的.如果用.net的“反编译”工具 ...
随机推荐
- [LeetCode系列] 二叉树最大深度求解问题(C++递归解法)
问: 给定二叉树, 如何计算二叉树最大深度? 算法描述如下: 如果当前节点为空, 返回0(代表此节点下方最大节点数为0) 如果当前节点不为空, 返回(其左子树和右子树下方最大节点数中的最大值+1) 上 ...
- java nio和bio
理解同步/异步,阻塞/非阻塞:https://juejin.im/entry/598da7d16fb9a03c42431ed3 2:http://qindongliang.iteye.com/blog ...
- Linux 文件名中包含特殊字符
文件和文件夹的名称中有特殊字符,操作有两种方式( - 在文件名称最前面除外). 例如:文件名为 a&b.c 1.通过转移符 "\" $ touch a\&b.c ...
- Linux和Windows的遍历目录下所有文件的方法对比
首先两者读取所有文件的方法都是采用迭代的方式,首先用函数A的返回值判断目录下是否有文件,然后返回值合法则在循环中用函数B直到函数B的返回值不合法为止.最后用函数C释放资源. 1.打开目录 #inclu ...
- map.js
function Map() { var struct = function(key, value) { this.key = key; this.value = value; } var put = ...
- struts2学习(5)拦截器简介以及例子执行过程
一.拦截器简介: 二.Struts2预定义拦截器&拦截器栈 在执行action之前和之后,拦截器进行了操作: 比如struts-default.xml中就有很多预定义的拦截器: 拦截器栈: ...
- [转] Jsp 重点
讲师:传智播客 方立勋 4个域对象: pageContext | page 域 request | request 域 session | session 域 servletContext | app ...
- MongoDB day02
1.非关系型数据库和关系型数据库比较 1. 不是以关系模型构建的,结构自由 2. 非关系型数据库不保证数据的一致性 3. 非关系型数据库可以在处理高并发和海量数据时弥补关系型数据库的不足 4. 非关系 ...
- Node.js的适用场景
高并发.聊天.实时消息推送.服务器做前端资源压缩
- python写个Hack Scan
前言: 之前逛SAFEING极客社区的时候 发现一款黑市卖2000多的软件,后面下载了 打不开.发现config文件里面有些不错的东西.总结了一下 有了以下的脚本. 脚本用处: [1]探测CMS(不敢 ...