题目描述:

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

Sample Output
2

数据范围
10%的数据 n,m≤3
30%的数据 n,m≤20
100%的数据 n,m≤100

题解:

(ps:好久没写blog了。。。
这题显然用网络流来解决。
最小割=最大流
用最少的栏杆将羊和狼隔开,可以转化成最小割的模型。
建立超级源S和超级汇T。将超级源与狼建边,流量为inf。将羊与超级汇建边,流量为inf。将狼与羊,空地与空地,空地与羊,狼与空地建边,流量为1。那么刷一次最小割(即刷DINIC)就是答案了。因为这样刷相当于找建围栏的最好方法。。。
代码如下:

#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
const int maxm=105,maxn=500005,inf=1<<30,flg[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int n,n1,m1,S,T,tot,ans,map[maxm][maxm],lnk[maxn],nxt[maxn],son[maxn],dep[maxn],w[maxn],que[maxn],cur[maxn];
inline int read(){int x=0; char ch=getchar();while (ch<'0'||ch>'9') ch=getchar();while (ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();return x;
}
bool bfs(){int head=0,tail=1; que[tail]=S;memset(dep,255,sizeof(dep)); dep[S]=0;while (head<tail) {head++;for (int j=lnk[que[head]];j!=-1;j=nxt[j])if (dep[son[j]]==-1&&w[j]>0) {dep[son[j]]=dep[que[head]]+1; que[++tail]=son[j];}}if (dep[T]==-1) return 0; else return 1;
}
int dfs(int x,int flow) {if (x==T) return flow;for (int& j=cur[x];j!=-1;j=nxt[j])if (dep[son[j]]==dep[x]+1&&w[j]!=0){int x=dfs(son[j],min(flow,w[j]));if (x) {w[j]-=x; w[j^1]+=x; return x;}}return 0;
}
int dinic(){int sum; ans=0;while (bfs()) {for (int i=1;i<=T;i++) cur[i]=lnk[i];while (sum=dfs(S,inf)) ans+=sum;}return ans;
}
void add(int x,int y,int z) {son[++tot]=y,w[tot]=z,nxt[tot]=lnk[x],lnk[x]=tot;son[++tot]=x,w[tot]=0,nxt[tot]=lnk[y],lnk[y]=tot;
}
int main(){n1=read(),m1=read(); n=n1*m1; S=++n,T=++n; tot=-1;memset(lnk,255,sizeof(lnk));memset(nxt,255,sizeof(nxt));for (int i=1;i<=n1;i++)for (int j=1;j<=m1;j++){map[i][j]=read();if (map[i][j]==1) add(S,(i-1)*m1+j,inf);else if (map[i][j]==2) add((i-1)*m1+j,T,inf);   }for (int i=1;i<=n1;i++)for (int j=1;j<=m1;j++)for (int k=0;k<4;k++) {int x=i+flg[k][0],y=j+flg[k][1];if (x<1||x>n1||y<1||y>m1||map[i][j]==2) continue;if (map[i][j]==1&&map[x][y]==1) continue;add((i-1)*m1+j,(x-1)*m1+y,1);}printf("%d\n",dinic());return 0;
}

BZOJ1412: [ZJOI2009]狼和羊的故事相关推荐

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

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

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

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

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

    bzoj100题啦  纪念一下. ----------------------------------------------------------------------------------- ...

  4. bzoj1412: [ZJOI2009]狼和羊的故事(最小割)

    传送门 首先,考虑只有狼和羊怎么办.我们把源点向所有羊连边,容$inf$,所有狼向汇点连边,容$inf$,然后羊向周围所有的狼连边,容$1$.那么,只要求一个割就能把狼和羊给分开,求一个最小割就是答案 ...

  5. [BZOJ1412][ZJOI2009]狼和羊的故事(最小割)

    题目描述 传送门 题解 首先建立源汇,对于每一个为1的点s->i,对于每一个为2的点i->t,然后每个点向它的四周连边. 这样做的原因是无论如何狼和羊不能通过任何道路连通. 最小割即为答案 ...

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

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

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

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

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

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

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

    1412: [ZJOI2009]狼和羊的故事 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3105  Solved: 1567 [Submit][ ...

最新文章

  1. 使用 Windows 命令行删除结果
  2. Windows:让Windows XP中的IIS支持多站点的工具
  3. ZooKeeper 集群:集群概念、选举流程、机器数量
  4. C++中结构体和类的区别和联系
  5. IO流入门-第十二章-ObjectInputStream_ObjectOutputStream
  6. 用java写一个日历_使用JAVA写一个简单的日历
  7. java了解异常_ID检测_Java入门第三季7-1简易扑克牌游戏(自定义玩家个数,玩家个数和ID异常检测)...
  8. artifacts屏蔽java文件输出_Java 是什么?
  9. HTTP,FTP,SMTP错误码
  10. 【渝粤题库】陕西师范大学202281 中央银行学II 作业(专升本)
  11. 【转】C# Lambda表达式
  12. python product函数
  13. 哔哩哔哩Java学习视频
  14. 直线段的矢栅转换算法(DDA算法、中心画线算法、Bresenham算法)
  15. 海康ehome协议分析(4):GPS上传
  16. vue3中套用echarts官网例子
  17. pclzip.lib.php,LimeSurvey
  18. 网站端服务器返回错误8001,云服务器 http server
  19. 预祝大家平安夜圣诞节快乐
  20. 常用的hook js

热门文章

  1. 笔记:美团智能配送系统的运筹优化实战
  2. Triangle程序编译
  3. 哈工大计算机系统大作业——程序人生-Hello’s P2P
  4. 安卓或苹果IOS的APP应用如何取名字?好的名字技巧?
  5. 人生短暂,持之以恒地做一件事情就会成功
  6. 17.scrapy框架简例使用
  7. 山东农村商业银行计算机笔试,2021年山东农村商业银行笔试备考:计算机科目高分复习方法...
  8. 1.3 项目经理的知识和技能
  9. 千万别把WIFI玩坏了!关于WIFI的新鲜玩法和商业模式探讨
  10. 第3周项目1-顺序表的基本运算