【BZOJ 1412】[ZJOI2009]狼和羊的故事

Description

“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。 通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。 Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。

Input

文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。

Output

文件中仅包含一个整数ans,代表篱笆的最短长度。

Sample Input

2 2
2 2
1 1

Sample Output

2

数据范围
10%的数据 n,m≤3
30%的数据 n,m≤20
100%的数据 n,m≤100
 
又是网络流,有没建出模型来……
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 using namespace std;
 6 const int inf=100000000,N=110;
 7 int fx[4]={0,0,1,-1},fy[4]={1,-1,0,0};
 8 struct ee{int to,next,f;}e[500001];
 9 int head[N*N],q[N*2*N],dis[N*N],a[N][N];
10 int S,T,n,m,cnt=1,ans,w;
11    
12 void ins(int u,int v,int f){
13     e[++cnt].to=v;e[cnt].f=f;e[cnt].next=head[u];head[u]=cnt;
14     e[++cnt].to=u;e[cnt].f=0;e[cnt].next=head[v];head[v]=cnt;
15 }
16    
17 bool bfs(){
18     for (int i=1;i<=T;i++) dis[i]=inf;
19     int h=0,t=1,now;
20     q[1]=S;dis[S]=0;
21     while(h!=t){
22         now=q[++h];
23         for (int i=head[now];i;i=e[i].next){
24             int v=e[i].to;
25             if (e[i].f&&dis[now]+1<dis[v]){
26                 dis[v]=dis[now]+1;
27                 if (v==T)return 1;
28                 q[++t]=v;
29             }
30         }
31     }
32     if (dis[T]==inf) return 0; return 1;
33 }
34    
35 int dinic(int now,int f){
36     if (now==T) return f;
37     int rest=f;
38     for (int i=head[now];i;i=e[i].next){
39         int v=e[i].to;
40         if (e[i].f&&dis[v]==dis[now]+1&&rest){
41             int t=dinic(v,min(rest,e[i].f));
42             if (!t) dis[v]=0;
43             e[i].f-=t;
44             e[i^1].f+=t;
45             rest-=t;
46             //if(t) printf("%d %d %d\n",now,v,e[i].f);
47         }
48     }
49     return f-rest;
50 }
51 int main(){
52     scanf("%d%d",&n,&m);
53     S=0,T=n*m+1;
54     for(int i=1;i<=n;i++)
55         for(int j=1;j<=m;j++)
56             scanf("%d",&a[i][j]);
57     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) 
58     if(a[i][j]==1) ins(S,(i-1)*m+j,inf);
59     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
60     if(a[i][j]==2) ins((i-1)*m+j,T,inf);
61     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
62         if(a[i][j]==1) {
63             for(int ii=0;ii<4;ii++) {
64                 int nx=i+fx[ii],ny=j+fy[ii];
65                 if(nx>n||nx<1||ny>m||ny<1||a[nx][ny]==1) continue;
66                 ins((i-1)*m+j,(nx-1)*m+ny,1);
67             }
68         }
69         else if(a[i][j]==0){
70             for(int ii=0;ii<4;ii++) {
71                 int nx=i+fx[ii],ny=j+fy[ii];
72                 if(nx>n||nx<1||ny>m||ny<1||a[nx][ny]==1) continue;
73                 ins((i-1)*m+j,(nx-1)*m+ny,1);
74             }
75         }
76     }
77     while(bfs()) 
78     ans+=dinic(S,inf);  
79     printf("%d",ans);
80 }

 

posted @ 2016-02-24 07:45  Alisahhh  阅读(279)  评论(0编辑  收藏  举报