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

分析

因为用篱笆将狼和羊分开,也就是将狼和羊割成两块,那么考虑做最小割。
连边:源点s向每只狼连一条无穷大的边,然后每只羊向汇点t连一条无穷大的边,接着每只狼和每块空地向相邻的每块空地和每只羊连一条1的边。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
const int mo=1000000007;
const int N=11105;
using namespace std;
int next[N*5],last[N],f[N*5],to[N*5],up[N*5],tot,n,m,a[111][111],d[N*10],dis[N];
int zz[4][2]=
{
 {0,1},
 {1,0},
 {0,-1},
 {-1,0}
};
int bj(int x,int y,int z)
{
	next[++tot]=last[x];
	last[x]=tot;
	to[tot]=y;
	f[tot]=z;
	
	up[tot]=++tot;
	up[tot]=tot-1;
	
	next[tot]=last[y];
	last[y]=tot;
	to[tot]=x;
	f[tot]=0;
	
}
int bfs()
{
	memset(dis,0,sizeof(dis));
	d[1]=0;
	dis[0]=1;
	int head=0,tail=1,k;
	while(head<tail)
	{
		k=d[++head];
		for(int i=last[k];i;i=next[i])
		{
			int j=to[i];
			if(f[i]>0 && !dis[j])
			{
				dis[j]=dis[k]+1;
				d[++tail]=j;
			}
		}
	}
	if(!dis[n*m+n]) return false;
		else return true;
}
int aug(int x,int y)
{
	if(x==n*m+n) return y;
	for(int i=last[x];i;i=next[i])
	{
		int j=to[i];
		if(dis[x]+1==dis[j] && f[i]>0)
		{
			int o=aug(j,min(y,f[i]));
			if(o>0)
			{
				f[i]-=o;
				f[up[i]]+=o;
				return o;
			}
		}
	}
	return 0;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			int pos=(i-1)*m+j;
			scanf("%d",&a[i][j]);
			if(a[i][j]==1)
				bj(0,pos,maxlongint);
			if(a[i][j]==2)
				bj(pos,n*m+n,maxlongint);
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			for(int k=0;k<=3;k++)
			{
				int xx=i+zz[k][0],yy=j+zz[k][1];
				if(xx<1 || yy<1 || xx>n || yy>m) continue;
				int pos=(i-1)*m+j,pos1=(xx-1)*m+yy;
				if(a[i][j]!=2)
					if(a[xx][yy]!=1) bj(pos,pos1,1);
			}
	int ans=0;
	while(bfs()) 
		ans+=aug(0,maxlongint);
	cout<<ans<<endl;
}

相关文章:

  • 2022-01-16
  • 2021-08-10
  • 2021-07-07
  • 2022-12-23
  • 2021-09-11
  • 2021-11-12
  • 2021-06-10
猜你喜欢
  • 2022-01-14
  • 2021-11-12
  • 2021-05-22
  • 2021-08-20
  • 2021-05-20
相关资源
相似解决方案