LA 6474 Drop Zone (最小割)
要添最少的挡板使所有的'D'不存在到达网格外的路径.
以每个格子向四个方向中可以到达的格子连容量为1的边, 从源点向所有'D' 连容量为4的边,网格外的点向汇点连一条容量为4的边.
答案就是这个容量网络的最小割,即最大流.
/*
最大流SAP
邻接表
思路:基本源于FF方法,给每个顶点设定层次标号,和允许弧。
优化:
1、当前弧优化(重要)。
1、每找到以条增广路回退到断点(常数优化)。
2、层次出现断层,无法得到新流(重要)。
时间复杂度(m*n^2)
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <utility>
#include <vector>
#define ms(a,b) memset(a,b,sizeof a)
using namespace std;
const int INF = ;
struct node {
int v, c, next;
} edge[];
int pHead[], SS, ST, nCnt;
int n, m;
int g[][];
int dx[] = {, , , -}, dy[] = {, , -, };
//同时添加弧和反向边, 反向边初始容量为0
void addEdge (int u, int v, int c) {
edge[++nCnt].v = v; edge[nCnt].c = c, edge[nCnt].next = pHead[u]; pHead[u] = nCnt;
edge[++nCnt].v = u; edge[nCnt].c = , edge[nCnt].next = pHead[v]; pHead[v] = nCnt;
}
inline int SAP (int pStart, int pEnd, int N) {
//层次点的数量 点的层次 点的允许弧 当前走过边的栈
int numh[INF], h[INF], curEdge[INF], pre[INF];
//当前找到的流, 累计的流量, 当前点, 断点, 中间变量
int cur_flow, flow_ans = , u, neck, i, tmp;
//清空层次数组,
ms (h, ); ms (numh, ); ms (pre, -);
//将允许弧设为邻接表的任意一条边
for (i = ; i <= N; i++) curEdge[i] = pHead[i];
numh[] = N;//初始全部点的层次为0
u = pStart;//从源点开始
//如果从源点能找到增广路
while (h[pStart] <= N) {
//找到增广路
if (u == pEnd) {
cur_flow = 1e9;
//找到当前增广路中的最大流量, 更新断点
for (i = pStart; i != pEnd; i = edge[curEdge[i]].v)
if (cur_flow > edge[curEdge[i]].c) neck = i, cur_flow = edge[curEdge[i]].c;
//增加反向边的容量
for (i = pStart; i != pEnd; i = edge[curEdge[i]].v) {
tmp = curEdge[i];
edge[tmp].c -= cur_flow, edge[tmp ^ ].c += cur_flow;
}
flow_ans += cur_flow;//累计流量
u = neck;//从断点开始找新的增广路
}
//找到一条允许弧
for ( i = curEdge[u]; i != ; i = edge[i].next)
if (edge[i].c && h[u] == h[edge[i].v] + ) break;
//继续DFS
if (i != ) {
curEdge[u] = i, pre[edge[i].v] = u;
u = edge[i].v;
}
//当前起点没有允许弧,从u找不到增广路
else {
//u所在的层次点减少一,且如果没有与当前点一个层次的点, 退出.
if ( == --numh[h[u]]) continue;
//有与u相同层次的点, 更新u的层次 ,回到上一个点
curEdge[u] = pHead[u];
for (tmp = N, i = pHead[u]; i != ; i = edge[i].next)
if (edge[i].c) tmp = min (tmp, h[edge[i].v]);
h[u] = tmp + ;
++numh[h[u]];
if (u != pStart) u = pre[u];
}
}
return flow_ans;
}
inline void build() {
char ch;
scanf ("%d %d", &n, &m);
ms (g, -), ms (pHead, ), nCnt = ;
for (int i = ; i <= n; i++) {
getchar();
for (int j = ; j <= m; j++) {
ch = getchar();
if (ch == '.') g[i][j] = ;
if (ch == 'D') g[i][j] = ;
}
}
n += , m += ;
SS = n * m, ST = SS + ;
for (int i = ; i < n; i++) {
for (int j = ; j < m; j++) {
int u = i * m + j;
if (i == || i == n - || j == || j == m - ) {
addEdge (u, ST, );
continue;
}
if (g[i][j] == ) {
for (int k = ; k < ; k++) {
int x = i + dx[k], y = j + dy[k];
int v = m * x + y;
if (g[x][y] != ) addEdge (u, v, );
}
}
if (g[i][j] == ) {
addEdge (SS, u, );
for (int k = ; k < ; k++) {
int x = i + dx[k], y = j + dy[k];
int v = m * x + y;
if (g[x][y] != ) addEdge (u, v, );
}
}
}
}
}
int cs;
int main() {
/*
建图,前向星存边,表头在pHead[],边计数 nCnt.
SS,ST分别为源点和汇点
*/
scanf ("%d", &cs);
while (cs--) {
build();
printf ("%d\n", SAP (SS, ST, n * m + ) );
}
return ;
}
LA 6474 Drop Zone (最小割)的更多相关文章
- LA 7277 Landscaping(最小割)
https://vjudge.net/problem/UVALive-7277 题意: 给出一个n*m的地图,.代表低坡,#代表高坡. 现在有n+m辆车分别从上端和左端出发,如果在行驶的过程中需要转换 ...
- 【LA 3487】Duopoly(图论--网络流最小割 经典题)
题意:C公司有一些资源,每种只有1个,有A.B两个公司分别对其中一些资源进行分组竞标,每组竞标对一些资源出一个总价.问C公司的最大收益. 解法:最小割.将A公司的竞标与源点相连,B公司的与汇点相连,边 ...
- 【BZOJ2127】happiness(最小割)
[BZOJ2127]happiness(最小割) 题面 Description 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了, ...
- BZOJ 1391: [Ceoi2008]order [最小割]
1391: [Ceoi2008]order Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1509 Solved: 460[Submit][Statu ...
- BZOJ-2127-happiness(最小割)
2127: happiness(题解) Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1806 Solved: 875 Description 高一 ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- BZOJ3438 小M的作物(最小割)
题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=3438 Description 小M在MC里开辟了两块巨大的耕地A和B(你可以认为 ...
- 最大流-最小割 MAXFLOW-MINCUT ISAP
简单的叙述就不必了. 对于一个图,我们要找最大流,对于基于增广路径的算法,首先必须要建立反向边. 反向边的正确性: 我努力查找了许多资料,都没有找到理论上关于反向边正确性的证明. 但事实上,我们不难理 ...
- bzoj1412最小割
太羞耻了,m n写反了(主要是样例n m相等) 建图方法比较高(ji)端(chu),对于可以加栅栏的地方连上1的边,然后求最小割即可 为了让代码优(suo)美(duan),我写了一个check,避免多 ...
随机推荐
- ServiceStack.Redis常用操作 - 事务、并发锁
一.事务 使用IRedisClient执行事务示例: using (IRedisClient RClient = prcm.GetClient()) { RClient.Add("key&q ...
- JavaScript高级程序设计20.pdf
用户代理检测 为了不在全局作用域中添加多余的变量,我们使用模块增强模式来封装检测脚本 以下是完整的用户代理字符串检测脚本,包括检测呈现引擎.平台.Window操作系统.移动设备和游戏系统 var cl ...
- linux性能优化
一.最小化安装系统二.关闭NetworkManager服务. NetworkManger服务如果启动,当你手动配置网卡时会发生冲突 [root@linuxangel ~]# /etc/init.d/N ...
- 基础排序算法之并归排序(Merge Sort)
并归排序是学习分治法 (Merge Sort) 的好例子.而且它相对于选择,插入,冒泡排序来说,算法性能有一定提升.我首先会描述要解决的问题,并给出一个并归排序的例子.之后是算法的思路以及给出伪代码. ...
- cas 单点登录配置
服务端配置 cas是个好东西,很灵活很好用,但是配置起来很麻烦 cas官方网站 http://downloads.jasig.org/ 下载服务端 CAS Server 3.3.3 Final 1.将 ...
- Cookie 和Session
会话: 简单理解: 用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 会话要解决的问题: 每个用户与服务器进行交互的过程中,各自会有一些数据,程序 ...
- Selenium+Java+TestNG环境配置
1. JDK 2.eclipse+TestNG >TestNG安装. Name:testng Location:http://beust.com/eclipse.如图: 3.seleniu ...
- OpenCV 2.4.9
2014.4.25 感谢那些參加开发.发送错误报告以及通过其它方式帮助我们的全部人和公司. 源代码如今已经可以从SourceForge和Github上下载了. 2.4.9版本号的帮助文章也更新到如今的 ...
- MFC——error LNK2005: "protected: static struct AFX_MSGMAP
好久没弄VC程序了,今天弄了下,还会用公司给的窗口重绘作为基类来实现,竟然报了这个错误. 找了一下是这里: 有个窗口重绘类是基类: class CBaseDlg : public CDialog 新建 ...
- QT QObject::connect函数的学习
从Qobject(QObject.h)源码中可以看到QObject::connect的定义是这样的: static bool connect(const QObject *sender, cons ...