【BZOJ-4261】建设游乐场 最大费用最大流
4261: 建设游乐场
Time Limit: 50 Sec Memory Limit: 256 MB
Submit: 21 Solved: 8
[Submit][Status][Discuss]
Description

Input
Output
Sample Input
1 1 1
1 0 0
1 0 0
48 94 1
78 78 81
1 12 60
Sample Output
HINT
N<=150,M<=30,Vi,j<=100
Source
Solution
蛮好的一道题,自己想了一段时间还是能想出来的QwQ
首先黑白染色,然后每个节点拆出横竖两个方向的节点$id_{1}$和$id_{2}$.
连边$S$到黑点,白点连$T$,容量为$2$,费用为$0$,限制两个方向;
黑点向黑点的每个方向连两条边,白点的每个方向向白点连两条边,容量都是$1$,费用一条为$val$,一条为$0$,表示选择转弯或者直道的价值。
然后黑点的每个方向向相邻白点的每个方向连边,容量为$1$,费用为$0$。
对于一个拐弯格子,会获得$2*val$的价值,对于一个直道格子,会获得$1*val$的价值,所以最后的答案就是$MaxCost-sum$。
代码还是很好写的,就是一开始细节出了问题WA了两次QwQ
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
} #define MAXN 30010
#define INF 0x7fffffff int N,M,mp[200][50],val[200][50],sum,tot; struct EdgeNode{
int next,to,cap,cost;
}edge[500010];
int head[MAXN],cnt=1;
inline void AddEdge(int u,int v,int w,int c) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].cap=w; edge[cnt].cost=c;}
inline void InsertEdge(int u,int v,int w,int c) {AddEdge(u,v,w,c); AddEdge(v,u,0,-c);} int Cost,S,T,dis[MAXN],mark[MAXN];
queue<int>q;
inline bool spfa()
{
for (int i=S; i<=T; i++) dis[i]=-INF,mark[i]=0;
queue<int>q;
q.push(S); dis[S]=0; mark[S]=1;
while (!q.empty()) {
int now=q.front(); q.pop(); mark[now]=0;
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]<dis[now]+edge[i].cost) {
dis[edge[i].to]=dis[now]+edge[i].cost;
if (!mark[edge[i].to]) q.push(edge[i].to),mark[edge[i].to]=1;
}
}
return dis[T]!=-INF;
} inline int dfs(int loc,int low)
{
mark[loc]=1;
if (loc==T) return low;
int used=0,w;
for (int i=head[loc]; i; i=edge[i].next)
if (edge[i].cap && !mark[edge[i].to] && dis[edge[i].to]==dis[loc]+edge[i].cost) {
w=dfs(edge[i].to,min(edge[i].cap,low-used));
edge[i].cap-=w; edge[i^1].cap+=w; used+=w; Cost+=w*edge[i].cost;
if (low==used) return used;
}
return used;
} inline int zkw()
{
int re=0;
while (spfa()) {
mark[T]=1;
while (mark[T]) {
for (int i=S; i<=T; i++) mark[i]=0;
re+=dfs(S,INF);
}
}
return re;
} int col[200][50],id[200][50][3],ID,dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
//id 0 主点 id 1 竖方向 id 3 横方向
inline bool Check(int x,int y) {return x>=1&&x<=N&&y>=1&&y<=M;}
int main()
{
N=read(),M=read();
for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)
mp[i][j]=read();
for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)
val[i][j]=read(),sum+=mp[i][j]? 0:val[i][j],col[i][j]=(i+j)&1; for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)
for (int k=0; k<=2; k++) id[i][j][k]=++ID; S=0; T=++ID; for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)
if (!mp[i][j]) {
if (col[i][j]) {
InsertEdge(S,id[i][j][0],2,0);
InsertEdge(id[i][j][0],id[i][j][1],1,val[i][j]);
InsertEdge(id[i][j][0],id[i][j][1],1,0);
InsertEdge(id[i][j][0],id[i][j][2],1,val[i][j]);
InsertEdge(id[i][j][0],id[i][j][2],1,0);
} else {
tot+=2;
InsertEdge(id[i][j][0],T,2,0);
InsertEdge(id[i][j][1],id[i][j][0],1,val[i][j]);
InsertEdge(id[i][j][1],id[i][j][0],1,0);
InsertEdge(id[i][j][2],id[i][j][0],1,val[i][j]);
InsertEdge(id[i][j][2],id[i][j][0],1,0);
}
} for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)
if (!mp[i][j] && col[i][j])
for (int k=0; k<=3; k++) {
int tx=i+dx[k],ty=j+dy[k];
if (Check(tx,ty) && !mp[tx][ty])
if (k==0 || k==2)
InsertEdge(id[i][j][1],id[tx][ty][1],1,0);
else
InsertEdge(id[i][j][2],id[tx][ty][2],1,0);
} int flow=zkw(); if (flow<tot) return puts("-1"),0; printf("%d\n",Cost-sum); return 0;
}
【BZOJ-4261】建设游乐场 最大费用最大流的更多相关文章
- BZOJ 4261: 建设游乐场
4261: 建设游乐场 Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 38 Solved: 16[Submit][Status][Discuss] ...
- bzoj 4261: 建设游乐场 费用流
题目 现在有一大块土地,可以看成N*M的方格.在这块土地上,有些格子内是崎岖的山地,无法建造任何东西:其他格子都是平原.现在打算在这块土地上建设一个游乐园.游乐园由若干条闭合的过山车轨道组成,每个平原 ...
- BZOJ 1927 星际竞速(最小费用最大流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1927 题意:一个图,n个点.对于给出的每条边 u,v,w,表示u和v中编号小的那个到编号 ...
- BZOJ 2424: [HAOI2010]订货(最小费用最大流)
最小费用最大流..乱搞即可 ------------------------------------------------------------------------------ #includ ...
- BZOJ 1070: [SCOI2007]修车 [最小费用最大流]
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 4936 Solved: 2032[Submit][Status] ...
- bzoj 1061 志愿者招募(最小费用最大流)
[Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 3792 Solved: 2314[Submit][Status][Di ...
- BZOJ 3550 Vacation(最小费用最大流)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3550 题意:给出3×n个数字,从中选出一些数字,要求每连续的n个数字中选出的数字个 ...
- BZOJ 2597 剪刀石头布(最小费用最大流)(WC2007)
Description 在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之为剪刀石头布情况.有的时候,无聊的人们会津津乐道 ...
- bzoj 1927 星际竞速 —— 最小费用最大流
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1927 首先注意到这是个DAG: 考虑每个点从哪里来,可以是瞬移来的,也可以是从某个点走过来的 ...
随机推荐
- html5 canvas 对角线渐变
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- CSS 实现图片灰度效果
非原创-从网上收索出来的文章 CSS实现图片灰度效果就是通过CSS样式让彩色图片呈现为灰色,相当于把一张图像的颜色模式调整为灰度,CSS可以通过以下几种方法来实现灰度效果. 方式1. IE滤镜 img ...
- 20155338 2016-2017-2 《Java程序设计》第6周学习总结
20155338 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 输入和输出 • 串流设计概念 要想活用输入/输出API,一定先要了解Java中如何以串流抽象 ...
- MFS - MooseFS 文件系统
MFSMooseFS 文件系统 可以实现RAID 功能:节约成本 实现在线扩展:是一种半分布式文件系统. 一.MFS文件系统的组成 1.mfsmaster 元数据服务器. 在整个体系中负责管理管理文件 ...
- SQL Server 索引(一)数据结构和存储结构
本文关注以下方面(本文所有的讨论基于SQL Server数据库): 索引的分类: 索引的结构: 索引的存储 一.索引定义分类 让我们先来回答几个问题: 什么是索引? 索引是对数据库表中一列或多列的值进 ...
- Jenkins的安装及使用(一)
操作环境:Windows7 一.环境准备 1 安装JDK 本文采用jdk-8u111-windows-x64.exe: 安装完成后配置环境变量. 2 配置tomcat 本文采用tomcat8,免安装版 ...
- 读写分离MYSQL类
2014年4月27日 12:34:08 概述: 1. 根据sql语句判断是连接读库还是写库 2. 链式调用$this->where()->get() 3. 不同的主机对应不同的实例, 不再 ...
- https-配置使用HTTPS的ASP.NET Web应用
有关HTTPS.SSL以及SSL证书的工作原理,参见 <HTTPS-HTTPS原理> <HTTPS-SSL证书> <HTTPS-攻击实例与防御> 本文将演示如何在I ...
- 测试开发之前端——No2.HTML5中的标签
HTML5中的标签. 标签 描述 <!--...--> 定义注释. <!DOCTYPE> 定义文档类型. <a> 定义超链接. <abbr> 定义缩写 ...
- 【OpenCV for Android】Android Studio JNI和NDK配置及采坑记录
在配置好Android studio的OpenCV环境后,我们就可以通过Java代码调用OpenCV的API了,但是在通常情况下,用Java代码编写图像处理算法的运行效率是没有C++代码高的,在应用层 ...