Description
Input
Output
Sample Input
5 8 2
00000000
02000000
00321100
02000000
00000000
……..
……..
..LLLL..
……..
……..
00000000
02000000
00321100
02000000
00000000
……..
……..
..LLLL..
……..
……..
Sample Output
1
HINT
//http://www.lydsy.com/JudgeOnline/problem.php?id=1066
//较难的一题最大流
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define inf 0x7ffffff
using namespace std;
struct edge{int to,w,next;}e[500001];
int n,m,d,cnt=1,num=0;
int start=0,end=1000; //超级源点 和 超级汇点
int mp[30][30],bh[30][30];
int dis[1500],head[1500];
void ini(int x,int y,int z){
e[++cnt].to=y;e[cnt].w=z;e[cnt].next=head[x];head[x]=cnt;
}
void insert(int x,int y,int z){
ini(x,y,z);ini(y,x,0);
}
queue<int>q;
bool bfs(){
q.push(start);
memset(dis,-1,sizeof(dis));
dis[start]=0;
while(!q.empty()){
int k=q.front();q.pop();
for(int i=head[k];i;i=e[i].next){
int kk=e[i].to;
if(dis[kk]==-1&&e[i].w>0){
dis[kk]=dis[k]+1;q.push(kk);
}
}
}
if(dis[end]==-1) return false;
return true;
}
int dfs(int x,int mn){
if(x==end) return mn;
for(int i=head[x];i;i=e[i].next){
int k=e[i].to;int a;
if(dis[k]==dis[x]+1&&e[i].w>0&&(a=dfs(k,min(e[i].w,mn))))
{
e[i].w-=a;
e[i^1].w+=a;
return a;
}
}
return 0;
}
bool excape(int x,int y)
{
return min(min(x,n+1-x),min(y,m+1-y))<=d;
}
bool judge(int x1,int y1,int x2,int y2){
if(x1==x2&&y1==y2) return false;
return (mp[x1][y1]&&mp[x2][y2]&&(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)<=d*d);
}
void dinic(){
int ans=0;
while(bfs()){
int a;
while(a=dfs(start,inf))
ans+=a;
}
printf("%d",num-ans);
}
int main(){
scanf("%d%d%d",&n,&m,&d);
char ch[30];
int tot=0;
for(int i=1;i<=n;i++){
scanf("%s",ch+1);
for(int j=1;j<=m;j++){
mp[i][j]=ch[j]-'0';
bh[i][j]=++tot;
}
}
for(int i=1;i<=n;i++)
{
scanf("%s",ch+1);
for(int j=1;j<=m;j++)
{
if(ch[j]=='L'){
insert(0,bh[i][j],1);
num++;
}
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(mp[i][j])
insert(bh[i][j],bh[i][j]+400,mp[i][j]);//拆点
if(excape(i,j)) insert(bh[i][j]+400,end,inf);//能走的话就连超级汇点
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int t1=max(1,i-d);t1<=min(i+d,n);t1++)
for(int t2=max(1,j-d);t2<=min(j+d,m);t2++)
if(judge(i,j,t1,t2)) insert(bh[i][j]+400,bh[t1][t2],inf);
dinic();
return 0;
}