网络流.
AC code:
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=1010;
const int M=100010;
const int INF=1<<28;
int n,m,k,S,T,he,ta,cnt=1,ans;
int head[N],q[N],d[N],cur[N];
char map[21][21];
struct Edge{
int v,f,next;
Edge() {}
Edge(int v,int f,int next):v(v),f(f),next(next) {}
}E[M];
int Abs(int x){
return x<0?-x:x;
}
int numb(int x,int y){
return m*(x-1)+y;
}
void addedge(int u,int v,int c){
E[++cnt]=Edge(v,c,head[u]);
E[++cnt]=Edge(u,0,head[v]);
head[u]=cnt-1;head[v]=cnt;
}
void read(){
scanf("%d%d%d",&n,&m,&k);
S=0;T=2*n*m+1;
for(int i=1;i<=n;i++){
scanf("\n");
for(int j=1;j<=m;j++) scanf("%c",&map[i][j]);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(map[i][j]=='0') continue;
addedge(numb(i,j),numb(i,j)+n*m,map[i][j]-'0');
for(int ii=1;ii<=n;ii++){
for(int jj=1;jj<=m;jj++){
if((i!=ii||j!=jj)&&map[ii][jj]!='0'&&Abs(i-ii)+Abs(j-jj)<=k)
addedge(numb(i,j)+n*m,numb(ii,jj),INF);
}
}
}
}
for(int i=1;i<=n;i++){
scanf("\n");
for(int j=1;j<=m;j++){
char c;
scanf("%c",&c);
if(c=='.') continue;
addedge(S,numb(i,j),1);
ans++;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(map[i][j]=='0'||(min(i,n-i+1)>k&&min(j,m-j+1)>k)) continue;
addedge(numb(i,j)+n*m,T,INF);
}
}
}
int BFS(){
he=ta=0;q[0]=S;
for(int i=S;i<=T;i++){
d[i]=0;cur[i]=head[i];
}
while(he!=ta+1){
int x=q[he++];
for(int i=head[x];i;i=E[i].next){
Edge e=E[i];
if(e.v==S||d[e.v]||(!e.f)) continue;
d[e.v]=d[x]+1;
q[++ta]=e.v;
}
}
return d[T];
}
int DFS(int x,int a){
if(x==T||(!a)) return a;
int flow,tag=0;
for(int &i=cur[x];i;i=E[i].next){
Edge e=E[i];
if(d[x]+1!=d[e.v]||(!e.f)) continue;
flow=DFS(e.v,min(e.f,a-tag));
tag+=flow;
E[i].f-=flow;
E[i^1].f+=flow;
if(!(a-tag)) break;
}
return tag;
}
void Dinic(){
while(BFS()) ans-=DFS(S,INF);
}
int main(){
read();
Dinic();
printf("%d",ans);
return 0;
}