网络流:
若该点能跳出边界,即与t连接一条指向t的容量为a[i][j]-‘0’的边,
若该点起始有蜥蜴,就与s连接一条指向该点的虚点的容量为a[i][j]的边(为什么是虚点后面讲)
若其中任意两点,x,y有石柱且可达:1.x,y之间连一条x指向y的虚点的容量为min(v[x],v[y])的边
2.x,y之间连一条y指向x的虚点的容量为min(v[x],v[y])的边
若该点有虚点,从虚点连一条指向实点的容量为v的边
在这张图上跑网络流,最大流就是可以跳出去的蜥蜴数
所以ans=sum-maxflow
为什么是虚点呢,因为若直接连向该点,则忽略了该点最多不能超过v个蜥蜴跳的限制,所以建立虚点,从虚点向实点连一条v容量的边就能保证这个条件
/**************************************************************
Problem: 1066
User: syh0313
Language: C++
Result: Accepted
Time:60 ms
Memory:13020 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
using
namespace
std;
const
int
inf=10000100;
const
int
maxe=500010;
const
int
maxd=1010;
const
int
xu=500;
int
n,m,d,s,t,topt,nt[maxe],st[maxe],to[maxe],cap[maxe];
int
inc[maxd],pre[maxd],q[1000010],head,tail,ans,sum;
bool
f[maxd],v[30][30];
char
a[30][30],c;
int
biao(
int
x,
int
y) {
return
(x-1)*m+y;}
void
add(
int
x,
int
y,
int
v)
{
to[topt]=y; nt[topt]=st[x]; st[x]=topt; cap[topt]=v; topt++;
to[topt]=x; nt[topt]=st[y]; st[y]=topt; cap[topt]=0; topt++;
}
bool
bfs()
{
for
(
int
i=1;i<=t;i++) pre[i]=-1,f[i]=1,inc[i]=0;
inc[s]=inf; q[1]=s; head=tail=1;
while
(head<=tail)
{
int
x=q[head++];
int
p=st[x];
while
(p!=-1)
{
if
(!inc[to[p]] && cap[p])
{
inc[to[p]]=min(inc[x],cap[p]);
pre[to[p]]=p;
q[++tail]=to[p];
}
p=nt[p];
}
}
if
(inc[t]==0)
return
0;
return
1;
}
int
main()
{
//freopen("1.in","r",stdin);
//freopen("my.out","w",stdout);
s=1001; t=1002;
memset
(st,-1,
sizeof
st);
scanf
(
"%d%d%d%c"
,&n,&m,&d,&c);
for
(
int
i=1;i<=n;i++)
{
for
(
int
j=1;j<=m;j++)
{a[i][j]=
getchar
(); add(biao(i,j),biao(i,j)+xu,a[i][j]-
'0'
);}
c=
getchar
();
}
for
(
int
i=1;i<=n;i++)
for
(
int
j=1;j<=m+1;j++)
{
c=
getchar
();
if
(c==
'L'
) {add(s,biao(i,j),1); sum++;}
}
for
(
int
i=1;i<=n;i++)
for
(
int
j=1;j<=m;j++)
{
if
((i<=d || n-i+1<=d || j<=d || m-j+1<=d)&& a[i][j]>=
'1'
&& a[i][j]<=
'4'
)
add(biao(i,j)+xu,t,inf);
if
(a[i][j]>=
'1'
&& a[i][j]<=
'4'
)
for
(
int
k=1;k<=n;k++)
for
(
int
l=1;l<=m;l++)
if
((i-k)*(i-k)+(j-l)*(j-l)<=d*d && a[k][l]>=
'1'
&& a[k][l]<=
'4'
)
{
if
(k==i && l==j)
continue
;
add(biao(i,j)+xu,biao(k,l),inf);
v[i][j]=1; v[k][l]=1;
}
}
while
(bfs())
{
ans+=inc[t];
int
se=pre[t];
while
(se!=-1)
{
cap[se]-=inc[t];
cap[se^1]+=inc[t];
se=pre[to[se^1]];
}
}
printf
(
"%d\n"
,sum-ans);
return
0;
}