主要还是网络流拆点建图一类技巧吧

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的更多相关文章

  1. hdu4862 2014多校B题/ 费用流(最优情况下用不大于K条路径覆盖)(不同的解法)

    题意: 一个数字矩阵,可以出发K次,每次可以从右边或者下面走,要求(在收益最大情况下)覆盖全图,不能则输出-1.(规则:每次跳一步的时候若格子数字相等则获得该数字的能量,每跳一步消耗距离的能量).每个 ...

  2. CFGYM 2013-2014 CT S01E03 D题 费用流模版题

    题意: n行, a房间的气球,b房间的气球 i行需要的气球,与a房的距离,b房的距离 求最小距离 #include <stdio.h> #include <string.h> ...

  3. [费用流][BZOJ1070]修车

    修车 题目描述 同一时刻有位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均 ...

  4. 【Luogu】P2488工作安排(费用流)

    题目链接 这题……费用流即可……(哇啊要被打死辣) 然而我printf("%d")爆零四次 好的心如死灰 #include<cstdio> #include<cs ...

  5. [bzoj 1449] 球队收益(费用流)

    [bzoj 1449] 球队收益(费用流) Description Input Output 一个整数表示联盟里所有球队收益之和的最小值. Sample Input 3 3 1 0 2 1 1 1 1 ...

  6. 【Tyvj1982】武器分配(费用流)

    题意:有N个人要从A个物品中各取一个,B个物品中各取一个,选取第i个A类物品和第j个B类物品的费用是(a[i]-b[j])^2 求最小总花费 n<=a,b<=80 a[i],b[i]< ...

  7. 【网络流24题】No.19 负载平衡问题 (费用流)

    [题意] G 公司有 n 个沿铁路运输线环形排列的仓库, 每个仓库存储的货物数量不等. 如何用最少搬运量可以使 n 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入文件示例input ...

  8. 【费用流】BZOJ1061: [Noi2008]志愿者招募(这题超好)

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 5291  Solved: 3173[Submit][Stat ...

  9. 【zkw费用流】[网络流24题]餐巾计划问题

    题目描述 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f ...

随机推荐

  1. thinkphp5修改入口文件位置及相应的问题

    问题1:thinkphp5修改入口文件 解决:参考手册 http://www.kancloud.cn/manual/thinkphp5/129746,然后需要把.htaccess跟入口文件放到同一目录 ...

  2. sublime配置nodejs运行调试js

    node.js调试javascript的配置 1. 首先到 nodejs.org 下载 Node.js 安装包并安装.2. 打开 Sublime Text 编辑器.选择菜单 Tools --> ...

  3. struts2.5+框架使用通配符与动态方法

    概述:struts2.5以后加强了安全性,下面就是安全配置引发的问题 通配符: 在学习struts框架时经常会使用到通配符调用方法,如下: <package name="usercru ...

  4. Python内建函数二

    内置函数二: 1.lambda (匿名函数) 为了解决一些简答的需求而设计的一句话函数.不需要def来声明. def func(n): return n*n f = lambda n: n*n 注意: ...

  5. Vue实例生命周期+vueRoter

    Vue实例生命周期 vue生命周期之beforeCreate 实例创建之前除标签外,所有的vue需要的数据,事件都不存在 vue生命周期之created 实例创建之后,data和事件已经被解析到,el ...

  6. Codeforces 1141F2(贪心、预处理)

    要点 一开始dp然后码力太辣鸡并且算法带假于是调了很久一交还WA在28-- 吐槽完毕.后来想拿栈优化dp时发现其实完全不需要dp,贪心选取即可,当前的不兼容就干脆不要它了,结果不会变差.然后想要什么就 ...

  7. Oracle .NET Core

    Oracle .NET Core Beta驱动已出,自己动手写EF Core Oracle https://www.cnblogs.com/yanweidie/p/9064609.html 使用.ne ...

  8. 过流监测芯片ADS720/723

    在电机应用领域经常需要用到过流监测和保护,allegro的ADS系列就可以很好实现.将芯片串接在电机之前,根据自己要保护的电流大小选择合适的量程,个根据自己ADC测量电压范围选择合适的灵敏度.这类芯片 ...

  9. 看懂物联网fr

        看懂物联网 2015-10-11 物联网世界 1.第三次IT浪潮 互联网时代的特征是信息驱动了生产力,无论众包.订单式生产这些理论:还是B2C.O2O各类业务模式:归根结底,是信息优化了生产关 ...

  10. fiddler手机抓包,支持前端代码调试

    手机用fiddler抓包 电脑最好是笔记本,这样能和手机保持统一局域网内:其他不多说,直接说步骤了. 一.对PC(笔记本)参数进行配置    1. 配置fiddler允许监听到https(fiddle ...