2024.3.22 【能够保存美好的唯一方式,便是遗憾。】
Friday 二月十三
P3159 CQOI2012 交换棋子
//2024.3.22
//by white_ice
#include <bits/stdc++.h>
using namespace std;
#define itn int
const int oo=1e3+10;
const int op=5e4+10;
const int inf=1e8+10;
const int dx[8]={-1,1,0,0,-1,-1,1,1};
const int dy[8]={0,0,-1,1,1,-1,1,-1};
itn ngm(int a,itn b){return a<b?a:b;}
int p,n,m;
int s,t;
itn fans,cans;
itn ua,ub;
struct nod{int v,nxt,w,r;}st[op];
int g[oo],vp=1;
void add(int x,int y,int z,int w){st[++vp]=(nod){y,g[x],z,w};g[x]=vp;}
void addp(int x,int y,int z,int w){add(x,y,z,w),add(y,x,0,-w);}
int dep[oo],cur[oo];
bool vis[oo];
queue<int> Q;
bool spfa(){
for(int i=1;i<=p;i++)
vis[i]=0,dep[i]=inf,cur[i]=g[i];
Q.push(s),vis[s]=1,dep[s]=0;
while(Q.size()){
int x=Q.front(); Q.pop();
vis[x]=0;
for(int i=g[x];i;i=st[i].nxt){
int v=st[i].v,d=st[i].r;
if(st[i].w&&dep[v]>dep[x]+d){
dep[v]=dep[x]+d;
if(!vis[v]){
vis[v]=1;
Q.push(v);
}
}
}
}
return dep[t]!=inf;
}
int dfs(int x,int fa){
if(!fa||x==t)
return fa;
int flow=0,f;
vis[x]=1;
for(int i=cur[x];i;i=st[i].nxt){
int v=st[i].v; cur[x]=i;
if(!vis[v]&&dep[x]+st[i].r==dep[v]&&
(f=dfs(v,min(fa,st[i].w)))>0){
st[i].w-=f;
st[i^1].w+=f;
flow+=f,fa-=f;
if(!fa){
vis[x]=0;
break;
}
}
}
return flow;
}
int us(int x,int y){return (x-1)*m+y;}
int spa[25][25],spb[25][25];
int main(){
cin >> n >> m;
p=t=2*n*m+2;
s=t-1;
char c[25];
for(int i=1;i<=n;i++){
scanf("%s",c);
for(int j=1;j<=m;j++)
if(c[j-1]=='1')
spa[i][j]=1,ub++;
}
for(int i=1;i<=n;i++){
scanf("%s",c);
for(int j=1;j<=m;j++)
if(c[j-1]=='1')
spb[i][j]=1,ua++;
}
if(ub!=ua){
puts("-1");
return 0;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(spa[i][j]&&!spb[i][j])
addp(s,us(i,j),1,0),fans++;
if(!spa[i][j]&&spb[i][j])
addp(us(i,j)+n*m,t,1,0);
}
}
for(int i=1,x;i<=n;i++){
scanf("%s",c);
for(int j=1;j<=m;j++){
x=c[j-1]-'0';
addp(us(i,j),us(i,j)+n*m,x>>1,0);
if((spa[i][j]^spb[i][j])&&(x&1))
addp(us(i,j),us(i,j)+n*m,1,0);
for(int k=0;k<8;k++){
int xt=i+dx[k],yt=j+dy[k];
if(xt<1||xt>n||yt<1||yt>m)
continue;
addp(us(i,j)+n*m,us(xt,yt),inf,1);
}
}
}
while(spfa()){
int d=dfs(s,inf);
fans-=d;
cans+=d*dep[t];
}
if(fans)
puts("-1");
else printf("%d\n",cans);
return 0;
}
字符串专题快练完了。