题目描述
“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。 通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。 Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。
输入输出格式
输入格式:
文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。
输出格式:
文件中仅包含一个整数ans,代表篱笆的最短长度。
输入输出样例
输入样例#1:
2 2
2 2
1 1
输出样例#1:
2
说明
数据范围
10%的数据 n,m≤3
30%的数据 n,m≤20
100%的数据 n,m≤100
分析:很显然的最小割嘛。S连羊,羊连空地,空地连狼,狼连T就可以了。
然后dfs一个垃圾错误搞得很烦。
代码:
// luogu-judger-enable-o2
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
const int inf=0x3f3f3f3f;
const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
using namespace std;
int n,m,s,t,cnt;
int a[105][105];
int ls[20001];
int dis[20001];
queue <int> q;
struct edge{
int y,w,op,next;
}g[100002];
int op(int x,int y)
{
return (x-1)*m+y;
}
void add(int x,int y,int w)
{
g[++cnt]=(edge){y,w,cnt+1,ls[x]};
ls[x]=cnt;
g[++cnt]=(edge){x,0,cnt-1,ls[y]};
ls[y]=cnt;
}
bool bfs()
{
for (int i=s;i<=t;i++) dis[i]=0;
dis[s]=1;
while (!q.empty()) q.pop();
q.push(s);
while (!q.empty())
{
int u=q.front();
q.pop();
for (int i=ls[u];i>0;i=g[i].next)
{
int v=g[i].y;
if ((dis[v]==0) && (g[i].w))
{
dis[v]=dis[u]+1;
if (v==t) return true;
q.push(v);
}
}
}
return false;
}
int dfs(int x,int maxf)
{
if ((x==t) || (maxf==0)) return maxf;
int ret=0;
for (int i=ls[x];i>0;i=g[i].next)
{
int y=g[i].y;
if ((dis[x]+1==dis[y]) && (g[i].w))
{
int f=dfs(y,min(maxf-ret,g[i].w));
g[i].w-=f;
g[g[i].op].w+=f;
ret+=f;
}
}
return ret;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++) scanf("%d",&a[i][j]);
}
s=0; t=n*m+1;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
if (a[i][j]==1) add(s,op(i,j),inf);
if (a[i][j]==2) add(op(i,j),t,inf);
if ((a[i][j]==1) || (a[i][j]==0))
{
for (int k=0;k<=3;k++)
{
int x=i+dx[k],y=j+dy[k];
if ((x>0) && (y>0) && (x<=n) && (y<=m))
{
if ((a[x][y]==2) || (a[x][y]==0))
add(op(i,j),op(x,y),1);
}
}
}
}
}
int ans=0;
while (bfs())
ans+=dfs(s,inf);
printf("%d",ans);
}