题目描述

“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” 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,流量都是 MAX;

在矩形中相邻的羊和狼连边,流量为 1 ;

对于0的点怎么处理呢?

我们把它默认为羊,羊向 0,0 向狼连边即可,流量均为1。

附代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#define MAXN 100010
#define MAXM 110
#define MAX 99999999
#define id(x,y) ((x-1)*m+y)
using namespace std;
const int fx[4]={1,-1,0,0},fy[4]={0,0,1,-1};
int n,m,s,t,c=2;
int head[MAXN],deep[MAXN],g[MAXM][MAXM];
struct node{int next,to,w;
}a[MAXN<<2];
inline int read(){int date=0,w=1;char c=0;while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}return date*w;
}
inline void add(int u,int v,int w){a[c].to=v;a[c].w=w;a[c].next=head[u];head[u]=c++;a[c].to=u;a[c].w=0;a[c].next=head[v];head[v]=c++;
}
bool bfs(){int u,v;queue<int> q;for(int i=s;i<=t;i++)deep[i]=0;deep[s]=1;q.push(s);while(!q.empty()){u=q.front();q.pop();for(int i=head[u];i;i=a[i].next){v=a[i].to;if(a[i].w&&!deep[v]){deep[v]=deep[u]+1;if(v==t)return true;q.push(v);}}}return false;
}
int dfs(int x,int limit){if(x==t)return limit;int v,sum,cost=0;for(int i=head[x];i;i=a[i].next){v=a[i].to;if(a[i].w&&deep[v]==deep[x]+1){sum=dfs(v,min(a[i].w,limit-cost));if(sum>0){a[i].w-=sum;a[i^1].w+=sum;cost+=sum;if(cost==limit)break;}else deep[v]=-1;}}return cost;
}
int dinic(){int ans=0;while(bfs())ans+=dfs(s,MAX);return ans;
}
void init(){n=read();m=read();s=0;t=n*m+1;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){g[i][j]=read();if(g[i][j]==1)add(id(i,j),t,MAX);if(g[i][j]==2)add(s,id(i,j),MAX);}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){if(g[i][j]==1)continue;for(int l=0;l<4;l++){int x=i+fx[l],y=j+fy[l];if(x<1||x>n||y<1||y>m)continue;if(g[x][y]==0||g[x][y]==1)add(id(i,j),id(x,y),1);}}
}
int main(){init();printf("%d\n",dinic());return 0;
}

洛谷P2598 [ZJOI2009]狼和羊的故事相关推荐

  1. 洛谷P2598 [ZJOI2009]狼和羊的故事 题解

    题目链接: https://www.luogu.org/problemnew/show/P2598 分析: 我们知道此题的目的是将狼和羊分割开,很容易想到狼在S,羊在T中. 首先,我们可以在狼,羊,空 ...

  2. 洛谷 - P2598 [ZJOI2009]狼和羊的故事(最大流最小割)

    题目链接:点击查看 题目大意:给出一个 n * m 的矩阵,每个格子都有三种状态:狼.羊和空地,现在需要在相邻方格之间添加篱笆,问最少需要添加多少篱笆才能使得狼和羊分开 题目分析:最大流最小割,建图方 ...

  3. 【洛谷P2598】狼和羊的故事【网络流】

    题目大意: 题目链接:https://www.luogu.org/problemnew/show/P2598 n × m n\times m n×m的网格中有些格子上有狼,有些有羊,有些是空地.网格外 ...

  4. P2598 [ZJOI2009]狼和羊的故事(网络流)

    我个人的理解: 可以先对原图进行建模为下图 其左端是狼,右端为羊,中间是连接狼和羊的路 现在为了让狼吃不到样,就要隔断狼和羊之间的连接 也就是 在这里,我们需要隔断狼和羊之间的连接,也就是转化成最小割 ...

  5. 题解 P2598 【[ZJOI2009]狼和羊的故事】

    P2598 [ZJOI2009]狼和羊的故事 题目描述 "狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......" Orez听到这首歌,心想:狼 ...

  6. [ZJOI2009]狼和羊的故事【最小割】

    题目链接 P2598 [ZJOI2009]狼和羊的故事 要让羊和狼都区别开来,需要的最小的割是多少?每只羊向四周有4个可能的方向,每只狼也是同样的,所以每个动物向周围可以跑出4个流,我们要建立栅栏,可 ...

  7. bzoj1412[ZJOI2009]狼和羊的故事

    bzoj1412[ZJOI2009]狼和羊的故事 题意: n*m网格,每个格子可能为狼.羊或空格.现在要在一些格子边界篱笆使羊狼分开,求最短篱笆.n,m≤100 题解: 最小割问题,建一个超级源和超级 ...

  8. BZOJ1412 ZJOI2009 狼和羊的故事 【网络流-最小割】

    BZOJ1412 ZJOI2009 狼和羊的故事 Description "狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......" Orez听 ...

  9. BZOJ 1412: [ZJOI2009]狼和羊的故事

    1412: [ZJOI2009]狼和羊的故事 >原题链接< Description "狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......& ...

最新文章

  1. 【错误记录】OD 调试器附加进程时找不到进程 ( CE 工具可以附加进程 )
  2. 阿里云https+nginx服务搭建
  3. c 语言怎么编译 .dll,将你的 C 语言代码编译成 .NET
  4. 分布式事务slides
  5. .db怎么复制到java里_MongoDB如何复制collection里的数据到另一个collection方法总结...
  6. opencv在android,OpenCV 在 Android 中的应用
  7. 特斯拉第四季度生产超30.5万台车 全年交付近百万台
  8. bzoj 1602: [Usaco2008 Oct]牧场行走(暴力LCA)
  9. 深度学习推荐系统--协同过滤推荐算法+实现代码
  10. ps去水印教程_ps怎么去水印?ps去水印的三种方法
  11. 徐家骏:我在华为工作十年的感悟
  12. STM32F103 DMA方式GPIO输出
  13. [数据库]MySQL表分区
  14. 强制退出hdfs安全模式
  15. uCOS事件相关函数代码理解
  16. 微信小程序 虚拟现实_开发虚拟现实应用程序的重要性
  17. 基于OpenWrt的Wol(wake on lan)远程唤醒
  18. 用于深度神经网络的语音信号预处理
  19. [iOS]Advanced Memory Management Programming Guide 高级内存管理编程指南(官方文档翻译)
  20. Mongdb重启后dirty很高,cache打满

热门文章

  1. 树莓派开发系列教程1——树莓派介绍
  2. 跟着我从零开始入门FPGA(一周入门XXOO系列)-设计一个只有4条指令的CPU
  3. web端对接语音通话(腾讯云)
  4. 欢乐颂2强势霸屏,黑科技已经植入生活,带我们飞
  5. 大众点评超详细爬虫系列2
  6. USB协议详解第5讲(USB描述符-接口描述符)
  7. 日剧《女王的教室》资源赏析
  8. 人工智能、大数据投身体育赛场 是搅局还是颠覆?
  9. 阿里云视频点播测试问题解决 (获取播放地址播放)
  10. 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 LNK2038 检测到“RuntimeLibrary”的不匹配项: 值“MD_DynamicRelease”不匹配值“MDd_DynamicDe