传送门

求无法逃离的蜥蜴总数的最小值就是求最多逃离的蜥蜴总数

所以显然考虑最大流,一个流量的路径就相当于一只蜥蜴逃离的路径

发现每个位置有一个最大经过次数,所以把每个位置拆成两个点$x,y$,$x$ 到 $y$ 连流量为最大经过次数的边

从源点向每个蜥蜴的初始位置的 $x$ 连一条流量为 $1$ 的边,表示初始时这些位置有蜥蜴

然后对于每一个位置 $u$, $dfs$ 找出所有走 $d$ 步以内能到的位置 $v$,然后从 $u$ 的 $y$ 点向 $v$ 的 $x$ 点连一条流量 $INF$ 的边,表示蜥蜴从 $u$ 跳到 $v$

注意 $dfs$ 判断一下到达边界的情况,有的话就往汇点连流量 $INF$ 的边

然后 总蜥蜴数 - 最大流 就是答案了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=2e5+,INF=1e9+,xx[]={,,,-},yy[]={,,-,};
int fir[N],from[N<<],to[N<<],val[N<<],cntt=;
inline void add(int a,int b,int c)
{
from[++cntt]=fir[a]; fir[a]=cntt;
to[cntt]=b; val[cntt]=c;
from[++cntt]=fir[b]; fir[b]=cntt;
to[cntt]=a; val[cntt]=;
}
int dep[N],Fir[N],S,T;
queue <int> Q;
bool BFS()
{
for(int i=S;i<=T;i++) Fir[i]=fir[i],dep[i]=;
dep[S]=; Q.push(S); int x;
while(!Q.empty())
{
x=Q.front(); Q.pop();
for(int i=fir[x];i;i=from[i])
{
int &v=to[i]; if(dep[v]||!val[i]) continue;
dep[v]=dep[x]+; Q.push(v);
}
}
return dep[T]>;
}
int DFS(int x,int mxfl)
{
if(x==T||!mxfl) return mxfl;
int fl=,res;
for(int &i=Fir[x];i;i=from[i])
{
int &v=to[i]; if(dep[v]!=dep[x]+||!val[i]) continue;
if( res=DFS(v,min(mxfl,val[i])) )
{
mxfl-=res; fl+=res;
val[i]-=res; val[i^]+=res;
if(!mxfl) break;
}
}
return fl;
}
inline int Dinic() { int res=; while(BFS()) res+=DFS(S,INF); return res; }
//以上网络流模板 int n,m,D,nm,id[][],ans;//id存每个位置的x, y=x+n*m
bool vis[][];//dfs时防止重复走
int mp[][];//mp存每个位置的限制
inline void dfs(int s,int x,int y,int stp)//起点,坐标x,y,走了stp步
{
if(stp==D) return;
vis[x][y]=;
for(int k=;k<;k++)
{
int tx=x+xx[k],ty=y+yy[k];
if(vis[tx][ty]) continue;
if(tx<||tx>n||ty<||ty>m) { add(nm+s,T,INF); continue; }//特判出界
if(mp[tx][ty]) add(nm+s,id[tx][ty],INF);
dfs(s,tx,ty,stp+);
}
vis[x][y]=;
}
int main()
{
int a; char c[];
n=read(),m=read(),D=read();
S=,T=(n*m<<)+; nm=n*m;
for(int i=;i<=n;i++)
{
scanf("%s",c+);
for(int j=;j<=m;j++)
{
id[i][j]=(i-)*m+j; mp[i][j]=a=c[j]-'';
if(a) add(id[i][j],nm+id[i][j],a);//每个位置的x向y连边
}
}
for(int i=;i<=n;i++)
{
scanf("%s",c+);
for(int j=;j<=m;j++)
{
if(mp[i][j]) dfs(id[i][j],i,j,);
if(c[j]=='L') add(S,id[i][j],),ans++;//初始蜥蜴
}
}
printf("%d\n",ans-Dinic());
return ;
}

P2472 [SCOI2007]蜥蜴的更多相关文章

  1. P2472 [SCOI2007]蜥蜴(网络流)

    P2472 [SCOI2007]蜥蜴 把每个点拆成2个点,两点之间连边的边权为石柱高度 新建虚拟源点$S$和汇点$T$ $S$向所有有蜥蜴的点连边,边权1 其他边都连$inf$ 剩下就是裸的$dini ...

  2. P2472 [SCOI2007]蜥蜴(网络最大流)

    P2472 [SCOI2007]蜥蜴 题目描述 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距 ...

  3. P2472 [SCOI2007]蜥蜴 (最大流)

    题目 P2472 [SCOI2007]蜥蜴 解析 这个题思路比较清晰,本(qi)来(shi)以(jiu)为(shi)无脑建图跑最大流,结果挂了,整了一个小时后重新建图才过的. 建立一个超级源点和一个超 ...

  4. P2472 [SCOI2007]蜥蜴(最大流)

    P2472 [SCOI2007]蜥蜴 自己第一道独立做题且一遍AC的网络流题纪念... 看到这道题我就想到网络流建图的方式了... 首先根据每个高度,我们将每个点拆成两个点限流.之后根据跳的最大距离, ...

  5. 洛谷P2472 [SCOI2007]蜥蜴 题解

    题目链接: https://www.luogu.org/problemnew/show/P2472 分析: 这道题用最大流解决. 首先构建模型. 一根柱子可以跳入和跳出,于是拆成两个点:入点和出点. ...

  6. 【题解】Luogu P2472 [SCOI2007]蜥蜴

    原题传送门 题目要求无法逃离的最少有多少 直接做肯定不好做,我们帮题目变一个说法:最多能逃离多少 这个询问一看就是最大流 考虑如何建图: 1.将S和每一个有蜥蜴的点连一条流量为1的边(每个蜥蜴只能用1 ...

  7. [洛谷P2472] [SCOI2007]蜥蜴

    题目链接: 蜥蜴 题目分析: 一道网络流,先来分析一下问题: 在一个\(r*c\)的图中分布了一些数,其他地方都用\(0\)填充,我们分别从指定的一些数出发,每次可以移动到周围距离为\(d\)以内的数 ...

  8. 题解 P2472 【[SCOI2007]蜥蜴】

    P2472 [SCOI2007]蜥蜴 题目背景 07四川省选 题目描述 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱 ...

  9. 1066: [SCOI2007]蜥蜴

    1066: [SCOI2007]蜥蜴 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3545  Solved: 1771[Submit][Status] ...

随机推荐

  1. JavaScript面向对象编程小游戏---贪吃蛇

    1 面向对象编程思想在程序项目中有着非常明显的优势: 1- 1 代码可读性高.由于继承的存在,即使改变需求,那么维护也只是在局部模块 1- 2 维护非常方便并且成本较低. ​ 2 这个demo是采用了 ...

  2. .NET基础 (07)异常的处理

    异常的处理1 如何针对不同的异常进行捕捉2 如何使用Conditional特性3 如何避免类型转换时的异常 异常的处理 1 如何针对不同的异常进行捕捉 C#中一个try块可以有多个catch块,每个c ...

  3. ACM 韩信点兵 、n的另一种阶乘、6174的问题

    3.6174问题 描述 假设你有一个各位数字互不相同的四位数,把所有的数字从大到小排序后得到a,从小到大后得到b,然后用a-b替换原来这个数,并且继续操作.例如,从1234出发,依次可以得到4321- ...

  4. el判断字符串是否为空

    ${empty 值}  返回true ,表示为空字符串; 在EL中empty对""和null的处理都返回true,而==null对""返回false,对null ...

  5. JVM 方法调用之解析

    方法调用并不等同于方法执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法),暂时还没有涉及到方法内部的具体运行过程.在程序运行时,进行方法调用是最普遍最频繁的操作,但Class文件 ...

  6. [LeetCode 题解]: Maximum Depth of Binary Tree

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  7. IIS 7.5 使用appliaction Initialization

    https://blogs.msdn.microsoft.com/amol/2013/01/25/application-initialization-ui-for-iis-7-5/ 待续 正在测试 ...

  8. sp_helptext输出错行问题解决

    相信,大家对sp_helptext存储过程一定不陌生,它可以帮你快速获取存储过程等对象的定义.但它有一个致命的缺点就是:每行最多返回255个nvarchar类型的字符,假如有一个编写不规范的存储过程, ...

  9. .Net Core 自动化部署:使用jenkins部署到linux docker容器运行

    上次我们说到.Net Core 自动化部署:使用docker版jenkins部署dotnetcore应用,这次我们使用jenkins发布我们的.NET Core站点到docker容器中运行,为后面的的 ...

  10. SQLlite 分页

    如果我要去11-20的Account表的数据 Select * From Account Limit 9 Offset 10; 以上语句表示从Account表获取数据,跳过10行,取9行 嗯,我觉得这 ...