分析
https://www.luogu.org/blog/dedicatus545/solution-p3159
代码
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #include<cmath> #include<cstdlib> #include<queue> #include<ctime> #include<vector> #include<set> #include<map> #include<stack> using namespace std; const int inf = 0x3f3f3f3f; int n,m,le[10010],ri[10010],now[10010],v[10010],beg[10010],end[10010]; int s,t,Ans,sum1,sum2; int head[100100],w[100100],c[100100],nxt[100100],to[100100]; int ano[100100],fm[100100],cnt; inline void add(int x,int y,int cost,int z){ nxt[++cnt]=head[x];head[x]=cnt;to[cnt]=y;w[cnt]=z;c[cnt]=cost;fm[cnt]=x; nxt[++cnt]=head[y];head[y]=cnt;to[cnt]=x;w[cnt]=0;c[cnt]=-cost;fm[cnt]=y; ano[cnt]=cnt-1;ano[cnt-1]=cnt; } inline void g(int id,int x,int y){ if(x<1||y<1||x>n||y>m)return; add(ri[id],le[(x-1)*m+y],0,inf); } inline void goadd(int i){ int x=i/m+1,y=i%m; if(y==0)x--,y=m; g(i,x-1,y-1),g(i,x-1,y),g(i,x-1,y+1); g(i,x,y-1),g(i,x,y+1); g(i,x+1,y-1),g(i,x+1,y),g(i,x+1,y+1); } queue<int>q; int iq[100100],d[100100],la[100100],nf[100100]; inline void work(){ while(1){ memset(d,0x3f,sizeof(d)); d[s]=0;q.push(s);iq[s]=1; nf[s]=inf; while(!q.empty()){ int x=q.front(); q.pop();iq[x]=0; for(int i=head[x];i;i=nxt[i]) if(w[i]&&d[to[i]]>d[x]+c[i]){ d[to[i]]=d[x]+c[i]; la[to[i]]=i; nf[to[i]]=min(nf[x],w[i]); if(!iq[to[i]]){ q.push(to[i]); iq[to[i]]=1; } } } int x=la[t],be=Ans; if(d[t]==inf)return; while(x){ w[x]-=nf[t]; w[ano[x]]+=nf[t]; Ans+=nf[t]*c[x]; x=la[fm[x]]; } } } int main(){ int i,j,k; scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ char s[110]; scanf("%s",s); for(j=1;j<=m;j++)beg[(i-1)*m+j]=s[j-1]-'0'; } for(i=1;i<=n;i++){ char s[110]; scanf("%s",s); for(j=1;j<=m;j++)end[(i-1)*m+j]=s[j-1]-'0'; } for(i=1;i<=n;i++){ char s[110]; scanf("%s",s); for(j=1;j<=m;j++)v[(i-1)*m+j]=s[j-1]-'0'; } int N=n*m; s=3*N+20,t=s+1; for(i=1;i<=N;i++)le[i]=i,now[i]=i+N,ri[i]=i+2*N; for(i=1;i<=N;i++){ int x=i/m+1,y=i%m; if(y==0)x--,y=m; if(beg[i]==0&&end[i]==1){ add(le[i],now[i],1,v[i]/2); add(now[i],ri[i],1,(v[i]+1)/2); sum1++; }else if(beg[i]==1&&end[i]==0){ add(le[i],now[i],1,(v[i]+1)/2); add(now[i],ri[i],1,v[i]/2); sum2++; }else { add(le[i],now[i],1,v[i]/2); add(now[i],ri[i],1,v[i]/2); } if(beg[i]==0)add(s,now[i],0,1); if(end[i]==0)add(now[i],t,0,1); goadd(i); } if(sum1!=sum2){ puts("-1"); return 0; } work(); printf("%d\n",Ans/2); return 0; }