CSU 1355 地雷清除计划

时间:2021-12-24 14:36:56

  题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1355

  好题,根本想不到是网络流。

  模型如图:

CSU 1355 地雷清除计划

  假想从右上角到左下角有一条阻拦线,我们就是需要把这条线剪短,搞出一个缺口,使得可以从(1,1)到(n,m)。这个与求网络流的最小割不谋而合,根据上面这个图建立网络流模型,对于a,b两个位置:

  1. 如果a.x == b.x 或者 a.y ==  b.y,那么当|a - b| <= 2*k+1时,从ab之间连一条边(如上图1 -> 3);

  2. 如果a.x != b.x 并且 a.y != b.y,那么 当|a - b| <= 2*k+2时,从ab之间连一条边(如上图2 -> 3);

  3. 如果a节点覆盖到了上边或右边,那么从超级源点连边到a节点(如上图源点到1和2);

  4. 如果a节点覆盖到了下边或左边,那么从a节点连边到超级汇点(如上图4和5到汇点);

  当然,必须对每个点进行拆点,这个就不多讲了。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define L(u) ((u) << 1)
#define R(u) ((u) << 1 | 1)
#define N 1005
#define M 200005
#define INF 0x3f3f3f3f int gap[N],dis[N],pre[N],cur[N];
int n, m, k, NE, s, t;
int head[N];
char g[][]; struct Node{
int c,pos,next;
}E[M]; struct Mine
{
int x, y;
int id;
}mine[]; inline void checkmin(int &a,int b) {if(a == - || a > b)a = b;} void add_edge(int u,int v,int c)
{
E[NE].c = c;
E[NE].pos = v;
E[NE].next = head[u];
head[u] = NE++; E[NE].c = ; // !反向初始为0
E[NE].pos = u;
E[NE].next = head[v];
head[v] = NE++;
} int sap()
{
memset(dis,,sizeof dis);
memset(gap,,sizeof gap);
memcpy (cur, head, sizeof dis);
int u=pre[s]=s,maxflow=,aug=-;
gap[]=n;
while(dis[s]<n)
{
loop:for(int &i=cur[u];i!=-;i=E[i].next)
{
int v=E[i].pos;
if(E[i].c && dis[u]==dis[v]+)
{
checkmin(aug, E[i].c);
pre[v]=u;
u=v;
if(v==t)
{
maxflow+=aug;
for(u=pre[u];v!=s;v=u,u=pre[u])
{
E[cur[u]].c-=aug;
E[cur[u]^].c+=aug;
}
aug=-;
}
goto loop;
}
}
int mindis=n;
for(int i=head[u];i!=-;i=E[i].next)
{
int v=E[i].pos;
if(E[i].c && mindis>dis[v])
{
cur[u]=i;
mindis=dis[v];
}
}
if((--gap[dis[u]])==) break;
gap[dis[u]=mindis+]++;
u=pre[u];
}
return maxflow;
} void init()
{
memset(head, -, sizeof head);
NE = ;
} int main()
{
int cas;
scanf("%d", &cas);
while(cas--)
{
scanf("%d%d%d", &n, &m, &k);
init(); int id = ;
for(int i = ; i < n; i++)
{
scanf("%s", g[i]);
for(int j = ; j < m; j++)
if(g[i][j] == '*')
{
mine[id].x = j;
mine[id].y = i;
mine[id].id = id++;
}
}
s = , t = L(id); for(int i = ; i < id; i++)
{
Mine a = mine[i];
if(a.y - k <= || a.x + k >= m-)
add_edge(s, L(i), INF); if(a.y + k >= n- || a.x - k <= )
add_edge(R(i), t, INF); for(int j = i; j < id; j++)
{
if(i == j)
add_edge(L(i), R(i), );
else
{
Mine b = mine[j];
if(((a.x == b.x) && (abs(a.y-b.y) <= *k+)) ||
((a.y == b.y) && (abs(a.x-b.x) <= *k+)))
{
add_edge(R(i), L(j), INF);
add_edge(R(j), L(i), INF);
} else if((a.x != b.x && a.y != b.y) && abs(a.x-b.x) + abs(a.y-b.y) <= *k+)
{
add_edge(R(i), L(j), INF);
add_edge(R(j), L(i), INF);
} }
}
} n = (id-) * + ; // 所构造图的总节点数
int res=sap();
printf("%d\n", res);
}
return ;
}

CSU 1355 地雷清除计划的更多相关文章

  1. csuoj 1355&colon; 地雷清除计划

    这是一个非常神奇的题: 感觉像一个模拟搜索: 但是竟然可以用网络流来解决: 直接粘题解把: 如果不能走通的话,必然说明能够从右上角(图外面)沿雷“跳” ,一直可以“跳”左下角(图外面) ,因此建好图之 ...

  2. Linux操作系统计划任务

    ++++++++++++++++++++++++++++++++++++++++++++++++标题:Linux操作系统的计划任务内容:计划任务分为单次任务和周期性任务,周期任务分为系统级计划任务和用 ...

  3. 三&period;cron计划任务

    • 用途:按照设置的时间间隔为用户反复执行某一项固 定的系统任务 • 软件包:cronie.crontabs • 系统服务:crond • 日志文件:/var/log/crond   • 使用 cro ...

  4. DBCC 命令2

    状态查询:收集和显示各类信息,状态检查. 如cachestats.pss.sqlmgrstats.memorystatus.proccache.freeproccache.freesystemcach ...

  5. 《Xenogears》&lpar;异度装甲)隐含的原型与密码

    <Xenogears>(异度装甲)隐含的原型与密码 X 彩虹按:一种高次元的“生命体”,因“事故”被抓来当成“超能源”,其实那不只是“无限的能源”而已,“它”是有意志的!在我们眼里看来,这 ...

  6. 【linux之crontab,启动】

    一.计划任务 atd at命令发布的任务计划 一次性的任务计划 at time ctrl+d 提交 time: 1.绝对时间:12:00 2.相对时间:+8 3.模糊时间:noon midnight ...

  7. DataGuard 单实例到RAC搭建

    背景简介: 本文为针对一次windows平台RAC数据库迁移至Linux平台RAC的笔记,基本步骤为: 1.搭建windows RAC到Linux 单实例数据库的DataGuard 2.做switch ...

  8. FtpCopy数据定时自动备份软件(FTP定时备份)

    1. 软件说明 FtpCopy是一款免费的FTP数据自动备份软件,如果FtpCopy对您有较大的帮助,欢迎捐赠我们,我们对您表示衷心的感谢! 如果有需求的话会一直更新下去,将软件做到极致! 有问题可直 ...

  9. 使用json改写网站

    效果图 json文件 https://raw.githubusercontent.com/sherryloslrs/timetable/master/timetable.json { "Ti ...

随机推荐

  1. Deep Learning 24:读论文&OpenCurlyDoubleQuote;Batch-normalized Maxout Network in Network”——mnist错误率为0&period;24&percnt;

    读本篇论文“Batch-normalized Maxout Network in Network”的原因在它的mnist错误率为0.24%,世界排名第4.并且代码是用matlab写的,本人还没装caf ...

  2. EditPlus

    # 批量更改文件编码 原文:EditPlus批量更改文件编码 # 标签位置设置到顶部 工具-参数设置-布局-文档选择器-位置

  3. gridview的行选择的一个问题

    我想实现这样一个效果:单击gridview的行内任意地方都可以选择该行(就是行内复选框被选中),同时修改该行的背景色.当再次单击行内任意地方又可以取消选择.另外,当单击选择行内复选框时,我希望可以选择 ...

  4. c&num;开发Mongo笔记第六篇

    之前写的五篇比较得到了大家的积极反馈,也有个别高手对我写我写出的代码进行了指教. 其中提到的我写的查询方法性能有问题,我想了想,如果mongo不是延时加载的话,那我的查询就真的有问题了,就成了查询出来 ...

  5. 函数lock&lowbar;rec&lowbar;get&lowbar;nth&lowbar;bit

    /*********************************************************************//** Gets the nth bit of a rec ...

  6. 深入理解JAVA多态原理

    之前一直知道多态是什么东西,平时敲代码也经常用到多态,但一直没有真正了解多态底层的运行机制到底是怎么样的,这两天才研究明白点,特地写下来,跟各位同学一起进步,同时也希望各位大神指导和指正. 多态的概念 ...

  7. 2014&sol;08&sol;24——升级stepbystep修复tc不刷新问题并加入杭电bc

    问题: 自从tc站点升级以后做题统计的tc一栏就不刷新了,为此全哥也更新了一下stepbystep的配置文件什么的,我仅仅要将其挂到server上即可了. 由于加了杭电的bc,看来这事儿不easy.还 ...

  8. Http请求封装基类HttpHelper&period;cs

    HttpHelper请求封装基类,支持get请求和POS请求http接口交互,为后面接口交互做准备. 1.HttpHelper帮助基类 using System; using System.Colle ...

  9. Ubuntu 安装phpMyAdmin &plus; 配置nginx

    0x01 安装phpMyAdmin ``` sudo apt-get install phpmyadmin ``` 0x02 添加链接 ``` sudo ln -s /usr/share/phpMyA ...

  10. JSX

    有一个 Babel 插件,用于在 Vue 中使用 JSX 语法,它可以让我们回到更接近于模板的语法上.JSX语法返回一个vnode对象 import AnchoredHeading from './A ...