【思维题 费用流 技巧】bzoj5403: marshland
主要还是网络流拆点建图一类技巧吧
Description
第一眼看到这题时候只会把每个点拆成4个方向;再强制定向连边防止成环;最后做一遍最大费用可行流。
然而这种做法显然比较复杂,且关于强制定向我也并不是很熟练……
再仔细研究一下题目的性质,发现危险度所处的格子奇偶性是相同的。这种性质使得我们可以以黑白染色的角度考虑强制定向的问题。
设$X+Y$为奇数的点为黑点;为偶数的点为白点。那么“折形”的限制就表述为每当选了一个黑点,就在上下、左右各选一个白点相连。对于费用流的建模,我们可以看做黑点放在中间,上下的白点在左边连向黑点;左右的白点在右边与黑点相连。首先来看中间的黑点,为了从费用流角度表示选取黑点,当然就是拆点连费用为$v[i][j]$的边。再是黑点两侧的点,需要注意的有:一、此处只是表示出了全图的一个部分,这里的白点还会和其他黑点产生关系,因此“两侧”的白点区别应当从所属行的奇偶性考虑。二、既然已经对黑点强制定向,那么“两侧”的白点就当分类分别处理与$S,T$的连边。
从这个角度建模后,由于对于每一个黑点都有关于相邻白点的$S,T$通路,那么每增广一次必然是在最大流的前提下保证选了当前最大费用。之所以提这一点,是因为有一些不恰当的建图方式把以S为起点的拓扑序安排得很混乱,以至于各个危险点之间的选取并不是完全分离的过程。
那么,剩下的就是一遍最大费用可行流的事情了。
#include<bits/stdc++.h>
typedef long long ll;
const int maxn = ;
const int maxNode = ;
const int maxm = ;
const int INF = 2e9; struct Edge
{
int u,v,f,c,cst;
Edge(int a=, int b=, int c=, int d=, int e=):u(a),v(b),f(c),c(d),cst(e) {}
}edges[maxm];
int n,lim,k,S,T;
int id[maxn][maxn],v[maxn][maxn];
int edgeTot,head[maxNode],nxt[maxm],bck[maxNode],flw[maxNode];
ll ans,cst[maxNode];
bool inq[maxNode],chk; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void addedge(int u, int v, int c, int cst)
{
edges[edgeTot] = Edge(u, v, , c, cst), nxt[edgeTot] = head[u], head[u] = edgeTot, ++edgeTot;
edges[edgeTot] = Edge(v, u, , , -cst), nxt[edgeTot] = head[v], head[v] = edgeTot, ++edgeTot;
}
void maxFlow()
{
std::queue<int> q;
memset(bck, , sizeof bck);
memset(flw, , sizeof flw);
memset(cst, -0x3f3f3f3f, sizeof cst);
q.push(S), flw[S] = INF, cst[S] = ;
for (int tmp; q.size(); )
{
tmp = q.front(), q.pop(), inq[tmp] = ;
for (int i=head[tmp]; i!=-; i=nxt[i])
{
int v = edges[i].v;
if (cst[tmp]+edges[i].cst > cst[v]&&edges[i].f < edges[i].c){
cst[v] = cst[tmp]+edges[i].cst, bck[v] = i;
flw[v] = std::min(flw[tmp], edges[i].c-edges[i].f);
if (!inq[v]) inq[v] = , q.push(v);
}
}
}
if (cst[T] < ) chk = false;
else{
for (int i=T; i!=S; i=edges[bck[i]].u)
edges[bck[i]].f += flw[T], edges[bck[i]^].f -= flw[T];
ans -= cst[T]*flw[T];
}
}
int main()
{
memset(head, -, sizeof head);
n = read(), lim = read(), k = read();
S = , T = n*n*+;
for (int i=, cnt=; i<=n; i++)
for (int j=; j<=n; j++)
id[i][j] = ++cnt, v[i][j] = read(), ans += v[i][j];
for (; k; --k) v[read()][read()] = INF;
for (int i=; i<=n; i++)
for (int j=; j<=n; j++)
if (v[i][j]!=INF){
if ((i+j)&) addedge(id[i][j], id[i][j]+n*n, , v[i][j]);
else{
if (i&){
addedge(S, id[i][j], , );
if (i > ) addedge(id[i][j], id[i-][j], , );
if (i < n) addedge(id[i][j], id[i+][j], , );
if (j > ) addedge(id[i][j], id[i][j-], , );
if (j < n) addedge(id[i][j], id[i][j+], , );
}else{
addedge(id[i][j], T, , );
if (i > ) addedge(id[i-][j]+n*n, id[i][j], , );
if (i < n) addedge(id[i+][j]+n*n, id[i][j], , );
if (j > ) addedge(id[i][j-]+n*n, id[i][j], , );
if (j < n) addedge(id[i][j+]+n*n, id[i][j], , );
}
}
}
chk = true;
for (; lim&&chk; --lim) maxFlow();
printf("%lld\n",ans);
return ;
}
END
【思维题 费用流 技巧】bzoj5403: marshland的更多相关文章
- hdu4862 2014多校B题/ 费用流(最优情况下用不大于K条路径覆盖)(不同的解法)
题意: 一个数字矩阵,可以出发K次,每次可以从右边或者下面走,要求(在收益最大情况下)覆盖全图,不能则输出-1.(规则:每次跳一步的时候若格子数字相等则获得该数字的能量,每跳一步消耗距离的能量).每个 ...
- CFGYM 2013-2014 CT S01E03 D题 费用流模版题
题意: n行, a房间的气球,b房间的气球 i行需要的气球,与a房的距离,b房的距离 求最小距离 #include <stdio.h> #include <string.h> ...
- [费用流][BZOJ1070]修车
修车 题目描述 同一时刻有位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均 ...
- 【Luogu】P2488工作安排(费用流)
题目链接 这题……费用流即可……(哇啊要被打死辣) 然而我printf("%d")爆零四次 好的心如死灰 #include<cstdio> #include<cs ...
- [bzoj 1449] 球队收益(费用流)
[bzoj 1449] 球队收益(费用流) Description Input Output 一个整数表示联盟里所有球队收益之和的最小值. Sample Input 3 3 1 0 2 1 1 1 1 ...
- 【Tyvj1982】武器分配(费用流)
题意:有N个人要从A个物品中各取一个,B个物品中各取一个,选取第i个A类物品和第j个B类物品的费用是(a[i]-b[j])^2 求最小总花费 n<=a,b<=80 a[i],b[i]< ...
- 【网络流24题】No.19 负载平衡问题 (费用流)
[题意] G 公司有 n 个沿铁路运输线环形排列的仓库, 每个仓库存储的货物数量不等. 如何用最少搬运量可以使 n 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入文件示例input ...
- 【费用流】BZOJ1061: [Noi2008]志愿者招募(这题超好)
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 5291 Solved: 3173[Submit][Stat ...
- 【zkw费用流】[网络流24题]餐巾计划问题
题目描述 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f ...
随机推荐
- Linux下FTP用户的使用配置
1.创建本地账户,用户名为自己的姓名拼音,使用本地用户测试,从以下几个方面来观察,账户 .密码.访问目录(可否查看上级目录) .上传下载的权限.
- css 文本溢出时显示省略号
.text-ellipsis { width:100px; height:60px; overflow: hidden;//隐藏滚动条 text-overflow:ellipsis; white-sp ...
- TaskFactory单例模式利用xml
/** * * Copyright (c) 1995-2009 Wonders Information Co.,Ltd. * 1518 Lianhang Rd,Shanghai 201112.P.R. ...
- Spring中的注入方式 和使用的注解 详解
注解:http://www.cnblogs.com/liangxiaofeng/p/6390868.html 注入方式:http://www.cnblogs.com/java-class/p/4727 ...
- NET Core2
NET Core的介绍 .NET Core 是一个通用开发平台,它由微软和开源社区共同管理(git hub的.NET开源社区): 他支持Windows,macOS和Linux,并且可以运行在硬件设 ...
- IO扩展芯片
PCF8574:一个I2C接口+INT中断引脚口扩展出一个可输出输出的并口P0~P7,INT可以用于中断响应
- POJ 3735 Training little cats 矩阵快速幂
http://poj.org/problem?id=3735 给定一串操作,要这个操作连续执行m次后,最后剩下的值. 记矩阵T为一次操作后的值,那么T^m就是执行m次的值了.(其实这个还不太理解,但是 ...
- HDU 1160 FatMouse's Speed LIS DP
http://acm.hdu.edu.cn/showproblem.php?pid=1160 同样是先按它的体重由小到大排,相同就按speed排就行. 这样做的好处是,能用O(n^2)枚举,因为前面的 ...
- Error: EPERM: operation not permitted,
转载自:https://blog.csdn.net/dong923700243/article/details/78989332 npm ERR! path E:\React\ReactNativeP ...
- Kendo 单页面应用(一)概述
Kendo 单页面应用(一)概述 Kendo 单页面应用(Single-Page Application,缩写为 SPA)定义了一组类用于简化 Web 应用(Rich Client)开发,最常见的单页 ...