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 ...
随机推荐
- [笔记] Access Control Lists (ACL) 学习笔记汇总
一直不太明白Windows的ACL是怎么回事,还是静下心来看一手的MSDN吧. [翻译] Access Control Lists [翻译] How Access Check Works Modify ...
- JQuery Div层滚动条控制(模拟横向滚动条在最顶端显示)
想让DIV层滚动条显示在顶端,CSS样式没找到相关属性,于是用2个DIV层来模拟做了一个.经测试IE浏览器上显示并不太美观!不知道是否还有更好的办法可以实现这功能呢? aaaaaaasssssss ...
- $《第一行代码:Android》读书笔记——第10章 Android网络编程
(一)WebView的用法 1.WebView也是一个普通的控件. 2.常用用法: WebView webView = (WebView)findViewById(R.id.web_view); we ...
- springboot-数据库
Spring-data-jpa jpa定义了一系列持久化的标准,比如hibernate就实现了这一标准. Springboot 的jpa就是hibernate的整合. 在pom文件中增加配置: < ...
- OpenCV图片拼接的两种方法
https://my.oschina.net/xiaot99/blog/226589 一.原图 1.jpg 2.jpg ...
- CMD mysql 备份脚本
创建.bat文件 echo. echo MySQL数据库备份脚本 echo ***************************** echo. echo 备份日期:%date% echo 备份时间 ...
- 安装Discuz开源论坛
11.添加mysql普通用户 接着上篇的lamp这篇安装Discuz 配置虚拟主机 1.打开虚拟主机配置 [root@NFS-31 ~]# vim /usr/local/apache2/conf/ht ...
- 基于Visual c++ 2012的php扩展开发 - HelloWord!
1.cmd进入命令行模式,并进入php-5.6.20-src/ext源代码的ext目录下输入命令php ext_skel_win32.php --extname=HelloWord,执行结果如下图: ...
- INSPIRED启示录 读书笔记 - 第36章 可用性与美感
两者缺一不可 交互设计和视觉设计完全是两回事 视觉设计可以满足用户的情感需求 良好的用户体验是交互设计师和视觉设计师合作的结果.他们共同配合产品经理定义产品
- C++中容器的使用(一)
C++中有两种类型的容器:顺序容器和关联容器. 顺序容器主要有vector.list.deque等.其中vector表示一段连续的内存,基于数组实现,list表示非连续的内存,基于链表实现,deque ...