【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
2 2
1 1
Sample Output
2
数据范围
10%的数据 n,m≤3
30%的数据 n,m≤20
100%的数据 n,m≤100
数据范围
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 }