1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #define M 100009
 5 #define inf 2139062143
 6 using namespace std;
 7 int n,m,a[102][102],cnt=1,T,ans,head[M],d[M],q[2*M],next[10*M],u[10*M],v[10*M];
 8 int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0};
 9 bool bfs()
10 {
11     memset(d,0,sizeof(int)*(T+1));
12     int h=0,t=1;
13     q[1]=0;
14     d[0]=1;
15     for(;h<t;)
16       {
17         h++;
18         int p=q[h];
19         for(int i=head[p];i;i=next[i])
20           if(!d[u[i]]&&v[i])
21             {
22                 d[u[i]]=d[p]+1;
23                 if(d[T])
24                   return 1;
25                 t++;
26                 q[t]=u[i];
27             }
28       }
29     return 0;
30 }
31 int dinic(int s,int f)
32 {
33     if(s==T)
34       return f;
35     int rest=f;
36     for(int i=head[s];i&&rest;i=next[i])
37       if(v[i]&&d[u[i]]==d[s]+1)
38         {
39             int now=dinic(u[i],min(rest,v[i]));
40             if(!now)
41               d[u[i]]=0;
42             v[i]-=now;
43             v[i^1]+=now;
44             rest-=now;
45         }
46     return f-rest;  
47 }
48 void jia1(int a1,int a2,int a3)
49 {
50     cnt++;
51     next[cnt]=head[a1];
52     head[a1]=cnt;
53     u[cnt]=a2;
54     v[cnt]=a3;
55     return;
56 }
57 void jia(int a1,int a2,int a3)
58 {
59     jia1(a1,a2,a3);
60     jia1(a2,a1,0);
61     return;
62 }
63 int main()
64 {
65     scanf("%d%d",&n,&m);
66     for(int i=1;i<=n;i++)
67       for(int j=1;j<=m;j++)
68         scanf("%d",&a[i][j]);
69     T=n*m+1;
70     for(int i=1;i<=n;i++)
71       for(int j=1;j<=m;j++)
72         {
73           if(a[i][j]==1)
74             jia(0,(i-1)*m+j,inf);
75           if(a[i][j]==2)
76             jia((i-1)*m+j,T,inf);
77             for(int k=0;k<4;k++)
78                 {
79                    int nx=i+xx[k],ny=j+yy[k];
80                    if(!nx||!ny||nx>n||ny>m)
81                      continue;
82                    if(a[nx][ny]!=a[i][j]||a[i][j]==0)
83                      jia((i-1)*m+j,(nx-1)*m+ny,1);
84                 }
85         }
86     for(;bfs();)
87       ans+=dinic(0,0x7fffffff);
88     printf("%d\n",ans);
89     return 0;
90 }

最小割,不同的点之间进行连边,空地于空地之间连边,易知最小割极为答案。

posted on 2016-03-13 05:36  xiyuedong  阅读(109)  评论(0编辑  收藏  举报