列表

详情


NC20488. [ZJOI2009]狼和羊的故事

描述

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

输入描述

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

输出描述

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

示例1

输入:

2 2
2 2 
1 1

输出:

2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 12ms, 内存消耗: 1196K, 提交时间: 2020-10-08 16:39:36

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=1e4+5,M=5e5+5,Inf=1e9;
const int dx[]={1,0,-1,0},
		  dy[]={0,1,0,-1};
struct Edge{int to,f,nxt;}e[M];
int n,m,s,t,fst[N],nf[N],tote,q[N],hd,tl,lev[N];
void adde(int u,int v,int f){
	e[++tote]=(Edge){v,f,fst[u]};fst[u]=tote;
	e[++tote]=(Edge){u,0,fst[v]};fst[v]=tote;
}
bool bfs(){
	memset(lev,-1,sizeof(lev));
	q[hd=tl=1]=s;lev[s]=0;
	while(hd<=tl){
		int u=q[hd++];
		for(int i=fst[u],v;~i;i=e[i].nxt)if(e[i].f&&lev[v=e[i].to]<0)
			lev[v]=lev[u]+1,q[++tl]=v;
	}
	return lev[t]>=0;
}
int dfs(int u,int lim){
	if(u==t)return lim;
	int res=0;
	for(int i=nf[u],v,f;~i;i=e[i].nxt){
		v=e[i].to;f=e[i].f;
		if(lev[v]==lev[u]+1&&f){
			int tmp=dfs(v,min(f,lim));
			e[i].f-=tmp;e[i^1].f+=tmp;lim-=tmp;res+=tmp;
			if(!lim){nf[u]=i;return res;}
		}
	}
	nf[u]=-1;return res;
}
int maxflow(){
	int res=0;
	while(bfs())memcpy(nf,fst,sizeof(nf)),res+=dfs(s,Inf);
	return res;
}
int a[105][105],id[105][105],dfn;
int main(){
	memset(fst,-1,sizeof(fst));tote=1;
	scanf("%d%d",&n,&m);
	s=n*m+1;t=n*m+2;
	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&a[i][j]),id[i][j]=++dfn;
	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
		if(a[i][j]==1)adde(s,id[i][j],Inf);
		else if(a[i][j]==2)adde(id[i][j],t,Inf);
	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(a[i][j]!=2){
		for(int k=0,x,y;k<4;k++){
			x=i+dx[k];y=j+dy[k];
			if(x>=1&&x<=n&&y>=1&&y<=m&&a[x][y]!=1)adde(id[i][j],id[x][y],1);
		}
	}
	printf("%d\n",maxflow());
	return 0;
}

上一题