【解题思路】

  考虑拆点,把每根石柱拆成两个点,具体可以理解为石柱底部和石柱顶部,能爬到石柱顶部的蜥蜴只有有限只,而且蜥蜴只有爬到了石柱顶部才能跳到其他石柱的底部。

  这样,考虑如下建图:

  将每个有蜥蜴的石柱底部和源点连边,容量为1;

  将每个可以跳出边界的石柱顶部和汇点连边,容量为∞;

  将每根石柱顶底相连,容量为该石柱最大承受蜥蜴个数;

  将可以相互跳达的任意两根石柱顶底相连,容量为∞。

  这样,该图的最大流即为最多可逃脱蜥蜴数,最终答案即为总蜥蜴数-最大流,复杂度o(r3c3d2)。

【参考代码】

 #include <bits/stdc++.h>
#define range(i,low,high) for(register int i=(low);i<(high);++i)
#define dange(i,high,low) for(register int i=(high);i>(low);--i) //#define __debug
#ifdef __debug
#define __function__(type) type
#define __procedure__ void
#else
#define __function__(type) __attribute__((optimize("-O2"))) inline type
#define __procedure__ __attribute__((optimize("-O2"))) inline void
#endif using namespace std; static const int N=,M=,INF=0x7f7f7f7f;
static int r,c,d,cardE=; int hed[N+],h[][]; struct edge
{
int fr,to,cap,nxt;
edge(
const int&f=,const int&t=,
const int&c=,const int&x=
):fr(f),to(t),cap(c),nxt(x) {}
}edg[M<<|]; __procedure__ addedge(
const int&fr,const int&to,const int&cp
)
{
edg[cardE]=edge(fr,to,cp,hed[fr]),hed[fr]=cardE++;
}
__procedure__ add_edge(
const int&fr,const int&to,const int&cp
)
{
addedge(fr,to,cp),addedge(to,fr,);
} //SAP {
static const int S=,T=;
int aug[N+],cur[N+],dis[N+],gap[N+],path[N+]; __function__(int) augment()
{
for(int i=T;i!=S;i=edg[path[i]].fr)
{
edg[path[i]].cap-=aug[T],edg[path[i]^].cap+=aug[T];
}
return aug[T];
} __function__(int) SAP(const int&N)
{
memset(aug,,sizeof aug),memset(gap,,sizeof gap);
memset(dis,,sizeof dis),aug[S]=INF,gap[]=N; int ret=;
range(i,,max(N,T)+) cur[i]=hed[i];
for(int fr=S;dis[S]<N;)
{
if(fr==T) fr=S,ret+=augment(); bool flag=;
for(int i=cur[fr];~i;i=edg[i].nxt)
{
int to=edg[i].to;
if(edg[i].cap&&dis[fr]==dis[to]+)
{
aug[to]=min(aug[fr],edg[i].cap),
path[to]=cur[fr]=i,fr=to,flag=; break;
}
}
if(flag)
{
if(!--gap[dis[fr]]) break; dis[fr]=N;
for(int i=hed[fr];~i;i=edg[i].nxt) if(edg[i].cap)
{
dis[fr]=min(dis[fr],dis[edg[i].to]+);
}
++gap[dis[fr]],cur[fr]=hed[fr];
if(fr!=S) fr=edg[path[fr]].fr;
}
}
return ret;
}
//} SAP __function__(bool) ok(const int&x,const int&y)
{
return x+d>=r||x<d||y+d>c||y<=d;
} __function__(int) calc(const int&x,const int&y,const bool&up)
{
return x*c+y+up*(N>>);
} int main()
{
scanf("%d%d%d",&r,&c,&d); int cnt=;
memset(hed,-,sizeof hed);
range(i,,r) range(j,,c+)
{
while(!isdigit(h[i][j]=getchar()));
add_edge(calc(i,j,),calc(i,j,),h[i][j]-='');
}
range(i,,r) range(j,,c+)
{
char ch=getchar();
for(;ch!='.'&&ch!='L';ch=getchar());
if(ch=='L') add_edge(S,calc(i,j,),),++cnt;
}
range(i,,r) range(j,,c+) if(ok(i,j))
{
add_edge(calc(i,j,),T,INF);
}
range(i,,r) range(j,,c+) range(k,-d,d+)
{
int rest=d-abs(k);
range(l,-rest,rest+) if(k||l)
{
int x=i+k,y=j+l;
if(x>=&&x<r&&y>&&y<=c&&h[i][j]&&h[x][y])
{
add_edge(calc(i,j,),calc(x,y,),INF);
}
}
}
return printf("%d\n",cnt-SAP(r*c+<<)),;
}

最新文章

  1. 怎么解决svn清理失败且路径显示乱码问题
  2. ObjectInputStream类和ObjectInputStream类的使用
  3. paip.执行shell cmd 命令uapi java php python总结
  4. linux命令介绍:df使用介绍
  5. a标签的href劫持,做判断后在跳转
  6. 【转】Android中如何使用Bundle传递对象[使用Serializable或者Parcelable] -- 不错
  7. ASP.NET MVC轻教程 Step By Step 9——分页
  8. NSLocalizedString不起作用
  9. VJ16216/RMQ/线段树单点更新
  10. Cdoefroces #354
  11. Oracle Job定时任务的使用详解
  12. Bootstrap3 表格-鼠标悬停
  13. vuex的购物车效果 index.js
  14. 性能测试七:jmeter进阶之文件上传下载、定时器
  15. RN全局的变量,方法,全局类,全局类方法
  16. PHP中MySQL、MySQLi和PDO的用法和区别
  17. Ubuntu16 源码方式安装postgresql数据库
  18. 【Linux】eclipse juno 边框过大的调整方法
  19. 给现有MVC项目增加Web API支持
  20. L240

热门文章

  1. 【leetcode】998. Maximum Binary Tree II
  2. USB驱动程序设计
  3. TIM4定时器功能设置
  4. 【Flutter学习】事件处理与通知之通知(Notification)
  5. CDN技术之--内容缓存工作原理
  6. rabbitmq安装-1
  7. Branch policies on Azure Repos
  8. Excel2016怎么批量删除空白行 如何删除空白行
  9. 4.Grafana展示监控数据
  10. upc组队赛5 Ingenious Lottery Tickets【排序】