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 ...
随机推荐
- Js onload 解析
Js onload的使用方法. 1.在script中调用 window.onload = function(){ function1(); function2(); function3(); }; 或 ...
- Python 5 面对对象编程
面向对象编程: 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强...” 面向过程编程 ...
- Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程
1.使用select模拟socketserver伪并发处理客户端请求,代码如下: import socket import select sk = socket.socket() sk.bind((' ...
- css系列(7)成品网页
本节介绍用css和html组合起来写的页面.(代码可以直接运行) (1)仿旧版腾讯微博注册页面:(文件夹地址:http://files.cnblogs.com/files/MenAng ...
- Linux 函数库
概述 函数库其实就是函数,只不过是系统所调用的函数.这样说吧,我写了一个软件,所有的功能都需要我自己完成吗?其实是不需要的,因为很多功能是别人已经写好的,我只需要拿来用就好了.这些有独立功能并且可以被 ...
- Hearbeat 介绍
Hearbeat 介绍 Linux-HA的全称是High-Availability Linux,它是一个开源项目,这个开源项目的目标是:通过社区开发者的共同努力,提供一个增强linux可靠性(reli ...
- jstl标签 c:if和c:choose
<c:if test="${test == null}">test为null</c:if> 其意思是,如果test 为 null,那么就打印 “test为n ...
- PHP开发环境MAMP for Windows
Windows上的整合PHP开发环境有很多,如:Windows上使用的Wampserver(http://www.wampserver.com/),跨平台的Xampp(https://www.apac ...
- 【BZOJ1854】游戏[SCOI2009](神奇贪心+并查集)
这道题和今年GDKOI的Day2T2很像(然而gdkoi的题用网络流可以A,这道题只能拿30). 网址:http://www.lydsy.com/JudgeOnline/problem.php?id= ...
- Ubuntu 16.04 安装 RabbitMQ
Ubuntu 16.04 安装 RabbitMQ(注意,服务器安全组需要添加15672 和5672端口) #1 更新 $ sudo apt-get update$ sudo apt-get upgra ...