挺裸的一道最小割
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(int i=l;i<=r;i++) 3 #define dec(i,l,r) for(int i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define NM 10000+5 10 #define nm 100000 11 using namespace std; 12 int read(){ 13 int x=0,f=1;char ch=getchar(); 14 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 15 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 16 return x*f; 17 } 18 struct edge{ 19 int t,v; 20 edge *next,*rev; 21 }e[nm],*h[NM],*o=e,*p[NM],*tmp[NM]; 22 void _add(int x,int y,int v){ 23 o->t=y;o->v=v;o->next=h[x];h[x]=o;o++; 24 } 25 void add(int x,int y,int v){ 26 _add(x,y,v);_add(y,x,0); 27 h[x]->rev=h[y];h[y]->rev=h[x]; 28 } 29 int n,m,tot,d[NM],b[105][105],_x,cnt[NM]; 30 const int dir[4][2]={0,1,0,-1,-1,0,1,0}; 31 bool check(int x,int y){ 32 return x&&x<=n&&y&&y<=m; 33 } 34 int maxflow(){ 35 int flow=0;edge *j; 36 inc(i,1,n)tmp[i]=h[i]; 37 cnt[0]=tot; 38 for(int x=0,s=inf;d[x]<tot;){ 39 for(j=tmp[x];j;j=j->next) 40 if(j->v&&d[j->t]+1==d[x])break; 41 if(j){ 42 s=min(s,j->v);tmp[x]=p[j->t]=j; 43 if((x=j->t)==n){ 44 for(;x;x=p[x]->rev->t){ 45 p[x]->v-=s; 46 p[x]->rev->v+=s; 47 } 48 flow+=s;s=inf; 49 } 50 }else{ 51 if(!--cnt[d[x]])break; 52 d[x]=tot; 53 link(x) 54 if(j->v&&d[j->t]+1<d[x]){ 55 d[x]=d[j->t]+1; 56 tmp[x]=j; 57 } 58 cnt[d[x]]++; 59 if(x)x=p[x]->rev->t; 60 } 61 } 62 return flow; 63 } 64 int main(){ 65 // freopen("data.in","r",stdin); 66 n=read();m=read(); 67 inc(i,1,n) 68 inc(j,1,m)b[i][j]=++tot; 69 tot++; 70 inc(i,1,n) 71 inc(j,1,m){ 72 _x=read(); 73 if(_x==1)add(0,b[i][j],inf); 74 if(_x==2)add(b[i][j],tot,inf); 75 inc(k,0,3) 76 if(check(i+dir[k][0],j+dir[k][1])) 77 add(b[i][j],b[i+dir[k][0]][j+dir[k][1]],1); 78 } 79 n=tot;tot++; 80 printf("%d ",maxflow()); 81 return 0; 82 }