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
最小割。源点向羊,狼向汇点连流量为INF的边。羊连空地,空地互连,空地连空地。【含义自己YY下】
然后跑最大流即可
【手残把源点向狼,狼向汇点的流量写成1了】
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int head[100001];
struct map
{
int f;
int s,t;
int next;
}a[400001];
int b[5001];
int edge;
int p;
int q[400001],d[400001];
inline void add(int s,int t,int f)
{
a[edge].next=head[s];
head[s]=edge;
a[edge].s=s;
a[edge].t=t;
a[edge].f=f;
}
inline bool bfs()
{
int l=0,r=0;
memset(q,0,sizeof(q));
r++;
q[r]=0;
memset(d,-1,sizeof(d));
d[0]=0;
int i,k;
while(l<r)
{
l++;
int k=q[l];
for(i=head[k];i!=0;i=a[i].next)
{
if(a[i].f>0&&d[a[i].t]==-1)
{
d[a[i].t]=d[k]+1;
r++;
q[r]=a[i].t;
}
}
}
if(d[p]>=0)
return true;
return false;
}
inline int dfs(int k,int s)
{
if(k==p)
return s;
int t=s;
int i;
for(i=head[k];i!=0;i=a[i].next)
{
if(d[a[i].t]==d[k]+1&&a[i].f>0)
{
int xx=dfs(a[i].t,min(s,a[i].f));
a[i].f-=xx;
if(i%2==0)
a[i-1].f+=xx;
else
a[i+1].f+=xx;
s-=xx;
}
}
return t-s;
}
inline int maxflow()
{
int s=0;
while(bfs())
s+=dfs(0,2100000000);
return s;
}
int map[101][101];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int i,j;
p=n*m+1;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%d",&map[i][j]);
if(map[i][j]==1)
{
edge++;
add(0,(i-1)*m+j,2100000000);
edge++;
add((i-1)*m+j,0,0);
}
else if(map[i][j]==2)
{
edge++;
add((i-1)*m+j,p,2100000000);
edge++;
add(p,(i-1)*m+j,0);
}
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(map[i][j]==1||map[i][j]==0)
{
if(i-1>0)
{
if(map[i-1][j]==2||map[i-1][j]==0)
{
edge++;
add((i-1)*m+j,(i-2)*m+j,1);
edge++;
add((i-2)*m+j,(i-1)*m+j,0);
}
}
if(j-1>0)
{
if(map[i][j-1]==2||map[i][j-1]==0)
{
edge++;
add((i-1)*m+j,(i-1)*m+j-1,1);
edge++;
add((i-1)*m+j-1,(i-1)*m+j,0);
}
}
if(i+1<=n)
{
if(map[i+1][j]==2||map[i+1][j]==0)
{
edge++;
add((i-1)*m+j,i*m+j,1);
edge++;
add(i*m+j,(i-1)*m+j,0);
}
}
if(j+1<=m)
{
if(map[i][j+1]==2||map[i][j+1]==0)
{
edge++;
add((i-1)*m+j,(i-1)*m+j+1,1);
edge++;
add((i-1)*m+j+1,(i-1)*m+j,0);
}
}
}
}
}
printf("%d\n",maxflow());
return 0;
}