现在艹道水题都要半小时+=感觉整个人都不好了
把点拆掉就可以了=因为次数限制在格子上
又因为走进走出要2次直接÷2=想想头和尾只踩了一次所以除以2前先+1就好了
#include <bits/stdc++.h>
#define rep(j,k,l) for (int j=k;j<=l;++j)
#define K 22
#define N 805
#define M 50005
using namespace std;
int to[M],ne[M],rest[M],cost[M],st[N],a[K][K],b[K][K],c[K][K];
int dis[N],f[N],que[N],used[N],last[N],road[N];
int n,m,cnt=1,ct1,ct2,head,tail,ans,fee;
void add(int k,int l,int o,int p){
to[++cnt]=l;
ne[cnt]=st[k];
st[k]=cnt;
rest[cnt]=o;
cost[cnt]=p;
}
bool Spfa(){
rep(i,0,n) dis[i]=100000,f[i]=0;
f[0]=1;dis[0]=0;head=0;tail=1;que[1]=0;used[0]=1;
while (head!=tail){
head=(head+1)%N;
int x=que[head];
used[x]=0;
for (int i=st[x];i;i=ne[i])
if (rest[i]&&dis[to[i]]>dis[x]+cost[i]){
dis[to[i]]=dis[x]+cost[i];
f[to[i]]=1;
road[to[i]]=i;
last[to[i]]=x;
if (!used[to[i]]){
tail=(tail+1)%N;
que[tail]=to[i];
used[to[i]]=1;
}
}
}
return f[n];
}
void rset(int k){
if (k!=0) rset(last[k]);
rest[road[k]]--;
rest[road[k]^1]++;
}
int main(){
scanf("%d%d",&n,&m);
rep(i,1,n) rep(j,1,m){
char ch=getchar();
while (ch<48||ch>57) ch=getchar();
a[i][j]=ch-48;
if (a[i][j]){
c[i][j]++;
add(0,(i-1)*m+j,1,0);
add((i-1)*m+j,0,0,0);
ct1++;
}
}
rep(i,1,n) rep(j,1,m){
char ch=getchar();
while (ch<48||ch>57) ch=getchar();
b[i][j]=ch-48;
if (b[i][j]){
c[i][j]++;
add((i-1)*m+j+n*m,n*m*2+1,1,0);
add(n*m*2+1,(i-1)*m+j+n*m,0,0);
ct2++;
}
}
if (ct1!=ct2){
printf("-1\n");
return 0;
}
rep(i,1,n) rep(j,1,m){
char ch=getchar();
while (ch<48||ch>57) ch=getchar();
c[i][j]=(c[i][j]+ch-48)/2;
add((i-1)*m+j,(i-1)*m+j+n*m,c[i][j],0);
add((i-1)*m+j+n*m,(i-1)*m+j,0,0);
if (i>1){
add((i-1)*m+j+n*m,(i-2)*m+j,100000,1);
add((i-2)*m+j,(i-1)*m+j+n*m,0,-1);
}
if (j>1){
add((i-1)*m+j+n*m,(i-1)*m+j-1,100000,1);
add((i-1)*m+j-1,(i-1)*m+j+n*m,0,-1);
}
if (i<n){
add((i-1)*m+j+n*m,i*m+j,100000,1);
add(i*m+j,(i-1)*m+j+n*m,0,-1);
}
if (j<m){
add((i-1)*m+j+n*m,(i-1)*m+j+1,100000,1);
add((i-1)*m+j+1,(i-1)*m+j+n*m,0,-1);
}
if (i>1&&j>1){
add((i-1)*m+j+n*m,(i-2)*m+j-1,100000,1);
add((i-2)*m+j-1,(i-1)*m+j+n*m,0,-1);
}
if (i<n&&j>1){
add((i-1)*m+j+n*m,i*m+j-1,100000,1);
add(i*m+j-1,(i-1)*m+j+n*m,0,-1);
}
if (i>1&&j<m){
add((i-1)*m+j+n*m,(i-2)*m+j+1,100000,1);
add((i-2)*m+j+1,(i-1)*m+j+n*m,0,-1);
}
if (i<n&&j<m){
add((i-1)*m+j+n*m,i*m+j+1,100000,1);
add(i*m+j+1,(i-1)*m+j+n*m,0,-1);
}
}
n=n*m*2+1;
while (Spfa()){
ans+=f[n];
fee+=f[n]*dis[n];
rset(n);
}
if (ans!=ct1) printf("-1\n");
else printf("%d\n",fee);
return 0;
}