bzoj 5403 Marshland

$n \leq 50$
sol:
放一个在 $x$ 处拐弯的 $L$ 形石头相当于在水平和垂直方向上各选一个与 $x$ 相邻的点,全局不能重复选
最小化危险度,相当于满足这些限制的情况下石头盖住的点危险度越大越好,而石头有各种各样的限制,考虑费用流
这是一个“只能增广 m 次的最大费用可行流”问题,我们增广到 m 次或者找出来的最长路为负即可
为了满足“不重复选”,可以拆点,每个入点向出点连流量 1,费用为危险度的边
因为每个危险点左右和上下各能选一个,相当于“每头牛都要分到一瓶可乐和一份午饭”(忘了这道题题号了...),可以把每个不危险的点分成“可乐”和“午饭”两类
因为选的两个不危险的点行数奇偶性不同,所以可以考虑按行数奇偶把非危险点分成两类
$S \space \rightarrow \space 每个行数为奇数的非危险点 \space \rightarrow \space 相邻的入点$
$相邻的出点 \space \rightarrow \space 每个行数为偶数的非危险点 \space \rightarrow \space T$
以上两类边流量 1,费用 0
然后愉快的流
#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline int read()
{
int x = ,f = ;char ch = getchar();
for(;!isdigit(ch);ch = getchar())if(ch == '-') f = -f;
for(;isdigit(ch);ch = getchar())x = * x + ch - '';
return x * f;
}
const int maxn = ,maxm = ,oo = ;
struct ZKW
{
int head[maxn], nx[maxn], inq[maxn], vis[maxn], dis[maxn];
int n, m, s, t, ans, cost;
queue<int> q;
struct Edge
{
int from, to, caps, cost;
Edge(){}
Edge(int _1, int _2, int _3, int _4) : from(_1), to(_2), caps(_3), cost(_4){}
}es[maxm];
ZKW(){memset(head, -, sizeof(head));}
void setn(int _){n = _;}
void AddEdge(int u, int v, int w, int c)
{
es[m] = Edge(u, v, w, c); nx[m] = head[u]; head[u] = m++;
es[m] = Edge(v, u, , -c); nx[m] = head[v]; head[v] = m++;
}
bool BFS()
{
for(int i = ;i <= n;i++)dis[i] = -oo;
dis[t] = ;inq[t] = ;q.push(t);
while(!q.empty())
{
int now = q.front();q.pop();
for(int i = head[now]; i != -; i = nx[i])
{
Edge& e = es[i^];
if(e.caps && dis[e.from] < dis[now] + e.cost)
{
dis[e.from] = dis[now] + e.cost;
if(!inq[e.from])
{
inq[e.from] = ;
q.push(e.from);
}
}
}
inq[now] = ;
}
if(dis[s] > ){cost = dis[s];return ;}
return ;
}
int DFS(int u, int a)
{
if(u == t || !a)return ans += cost * a, a;
if(vis[u])return ; vis[u] = ;
int flow = , f;
for(int i = head[u]; i != -; i = nx[i])
{
Edge& e = es[i];
if(dis[e.to] == dis[u] - e.cost && (f = DFS(e.to, min(e.caps, a))))
{
e.caps -= f; es[i^].caps += f;
a -= f; flow += f;
if(!a)return flow;
}
}
return flow;
}
int MaxCostFlow(int _s, int _t, int tms)
{
s = _s, t = _t;
int flow = , f;
for(int i = ; i <= tms; i++) if(BFS()) {memset(vis, , sizeof(vis)); flow += DFS(s, oo);}
return flow;
}
} sol;
int n, m, k, s, t, ans;
int mat[][],mem[][][],dfn,b[maxn];
inline int pos(int x, int y, int type)
{
return n * n * (type - ) + (x - ) * n + y;
}
int main()
{
n = read(), m = read(), k = read();
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++) mat[i][j] = read();
s = , t = n * n * + ;
sol.setn(t + );
for(int i = ; i <= k; i++)
{
int x = read(), y = read();
b[pos(x, y, )] = ;
} for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
{
ans += mat[i][j];
if(b[pos(i, j, )])continue;
if((i + j) & )
sol.AddEdge(pos(i, j, ), pos(i, j, ), , mat[i][j]);
else
{
if(i & )
{
sol.AddEdge(s, pos(i, j, ), , );
if(i > ) sol.AddEdge(pos(i, j, ), pos(i - , j, ), , );
if(j > ) sol.AddEdge(pos(i, j, ), pos(i, j - , ), , );
if(i < n) sol.AddEdge(pos(i, j, ), pos(i + , j, ), , );
if(j < n) sol.AddEdge(pos(i, j, ), pos(i, j + , ), , );
}
else
{
sol.AddEdge(pos(i, j, ), t, , );
if(i > ) sol.AddEdge(pos(i - , j, ),pos(i, j, ), , );
if(j > ) sol.AddEdge(pos(i, j - , ),pos(i, j, ), , );
if(i < n) sol.AddEdge(pos(i + , j, ), pos(i, j, ), , );
if(j < n) sol.AddEdge(pos(i, j + , ), pos(i, j, ), , );
}
}
} sol.MaxCostFlow(s, t, m);
cout << ans - sol.ans << endl;
}
不知道为什么 在限制增广次数的时候 ZKW 的多路增广是错的
bzoj 5403 Marshland的更多相关文章
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 【sdoi2013】森林 BZOJ 3123
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
- 【清华集训】楼房重建 BZOJ 2957
Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...
- 【splay】文艺平衡树 BZOJ 3223
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 ...
- bzoj 刷水
bzoj 3856: Monster 虽然是sb题,,但是要注意h可能<=a,,,开始忘记判了WA得很开心. #include <iostream> #include <cst ...
随机推荐
- iOS Swift 熊猫🐼跑酷 第一个小项目
前言:想用swift 写个小游戏 慢慢转化 能写出 ARKit来.但是又不能一口吃个胖子,慢慢来,在网络视频教程中撸了视频教学,断断续续看了半个多月,基本实现了 游戏主角
- 计算机网络概述---传输层 UDP和TCP
传输层的功能 传输层为应用进程间提供端到端的逻辑通信(网络层是提供主机之间的逻辑通信), 传输层两大重要的功能:复用 和 分用. 复用:在发送端,多个应用进程公用一个传输层: 分用:在接收端,传输层会 ...
- 自己动手编译Android源码(超详细)
http://www.jianshu.com/p/367f0886e62b 在Android Studio代码调试一文中,简单的介绍了代码调试的一些技巧.现在我们来谈谈android源码编译的一些事. ...
- Linux串口编程(中断方式和select方式)
Linux下的串口编程,在嵌入式开发中占据着重要的地位,因为很多的嵌入式设备都是通过串口交换数据的.在没有操作系统的我们可以使用UART的中断来出来数据的接受和发送,而在Linux操作系统下,我们也可 ...
- jQuery可放大预览的图片滑块
在线演示 本地下载
- 安装mysql5.7后无法启动,/var/run/mysqld 目录每次重启后都需要手动去创建--终极解决方案
鉴于很多童鞋反应,mysql5.7安装后出现无法启动,建立/var/run/mysqld 并赋权mysql用户解决了启动的问题,但是重启系统后又出现无法启动的问题,导致/var/run/mysqld ...
- mongodb 的主从配置
mongoDB主从配置如下: 主库: port=27017 dbpath=/usr/local/mongodb/data logpath=/usr/local/mongodb/log/mongodb. ...
- EF Code-First 学习之旅 继承策略
Code First中有三种不同的方法表示继承层次关系 1.Table per Hierarchy (TPH): 这种方法建议用一个表来表示整个类的继承层次关系,表中包含一个识别列来区分继承类,在En ...
- 【转】Android应用中使用AsyncHttpClient来异步网络数据
摘要: 首先下载AsyncHttpClient的库文件,可以自行搜索,可以到下面地址下载 http://download.csdn.net/detail/xujinyang1234/5767419 测 ...
- YII2笔记之三
activeform布局findAll等不能满足where, order by, limit,底层调用了findByConditioncol-md col-lg的使用 view的方法,前三个常用ren ...