P2598 [ZJOI2009]狼和羊的故事

题目描述

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

输入输出格式

输入格式:

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

输出格式:

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


分析

要保证篱笆长最小而把狼和羊分开来,我们可以联想到最小割模型。一个图的最小割就是把图分为两个部分(源点及汇点不在同一部)的边权和。最小割可以用最大流算法求得。

建模

要说到网络流,重点就在于建模了,我们怎么把此网格图转换为最大流网络流呢?其实对于一个格子,我们可以把它看做与上下左右四个方向都有一条连边,而把这个格子抽象成一个点,如下图:

依据题意和最大流的经验,我们可以连边了:(我以羊的一部作为源点,所以)源点连羊,狼连汇点,若相邻的点事狼,则连一条容量为1的边(他的模型意义是:把羊和狼分开【割】需要消耗“1”)

但是对于0怎么办呢?这是本题的难点

可以思索一下,若是把0全部归为狼或者羊吧,感觉又会有更优解(事实也是这样,因为狼和羊是等价的【把狼从羊中隔离开来等价于把羊从狼中隔离开来】,所以这样单方面划分是肯定不正确的),那么怎么办呢

你可能不会,但你的最大流算法一定知道怎么做

我们这样连:源点---羊--(边A,c=1)--0--(边B, c=1)--狼---汇点

试想一下,你的篱笆的作用是分割狼和羊,0这些格子要么被划分到狼的领地,要么被划分到羊的领地,若是划分到狼那边,你的算法会割开靠近羊的那条边 A ,要是划分到羊这边,他会自动割开靠近狼的边 B 。一定不存在一种割的方式,使 A 和 B 同时被割开,因为你的算法知道,割一条就足以分开两点,不需要割第二条

所以,放手给程序去跑吧

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int RD(){
int out = 0,flag = 1;char c = getchar();
while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
return flag * out;
}
const int maxn = 100019,INF = 1e9;
int nume = 1;
int lenx,leny;
int map[190][190];
int mx[4] = {1,-1,0,0};
int my[4] = {0,0,1,-1};
int s,t,maxflow;
int head[maxn];
struct Node{
int v,dis,nxt;
}E[maxn << 2];
void add(int u,int v,int dis){
E[++nume].nxt = head[u];
E[nume].v = v;
E[nume].dis = dis;
head[u] = nume;
}
int lev[maxn];
bool bfs(){
queue<int>Q;
memset(lev,0,sizeof(lev));
Q.push(s);
lev[s] = 1;
while(!Q.empty()){
int u = Q.front();
Q.pop();
for(int i = head[u];i;i = E[i].nxt){
int v = E[i].v;
if(E[i].dis && !lev[v]){
lev[v] = lev[u] + 1;
Q.push(v);
if(v == t)return 1;
}
}
}
return 0;
}
int Dinic(int u,int flow){
if(u == t)return flow;
int rest = flow,k;
for(int i = head[u];i;i = E[i].nxt){
int v = E[i].v;
if(E[i].dis && lev[v] == lev[u] + 1 && rest){
k = Dinic(v,min(rest,E[i].dis));
if(!k)lev[v] = 0;
E[i].dis -= k;
E[i ^ 1].dis += k;
rest -= k;
} }
return flow - rest;
}
int getindex(int x,int y){
return (x - 1) * leny + y;
}
bool judge(int x,int y){
if(x < 1 || x > lenx || y < 1 || y > leny)return 0;
return 1;
}
/*for(int i = 1;i <= lenx;i++){
for(int j = 1;j <= leny;j++){ }
}*/
void build(){
for(int i = 1;i <= lenx;i++){
for(int j = 1;j <= leny;j++){
if(map[i][j] == 2){
add(s,getindex(i,j),INF);
add(getindex(i,j),s,0);
}
else if(map[i][j] == 1){
add(getindex(i,j),t,INF);
add(t,getindex(i,j),0);
}
}
}
for(int i = 1;i <= lenx;i++){
for(int j = 1;j <= leny;j++){
if(map[i][j] == 2 || map[i][j] == 0){
for(int k = 0;k < 4;k++){
int nx = i + mx[k],ny = j + my[k];
if(!judge(nx,ny))continue;
if(map[nx][ny] == 1 || map[nx][ny] == 0){
add(getindex(i,j),getindex(nx,ny),1);
add(getindex(nx,ny),getindex(i,j),0);
}
}
}
}
}
}
int main(){
lenx = RD();leny = RD();
for(int i = 1;i <= lenx;i++){
for(int j = 1;j <= leny;j++){
map[i][j] = RD();
}
}
s = lenx * leny + 1,t = s + 1;
build();
int flow = 0;
while(bfs())while(flow = Dinic(s,INF))maxflow += flow;
printf("%d\n",maxflow);
return 0;
}

题解 P2598 【[ZJOI2009]狼和羊的故事】的更多相关文章

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

    P2598 [ZJOI2009]狼和羊的故事 源点和所有狼连 $inf$ 的边 所有羊和汇点连 $inf$ 的边 所有点向四周连 $1$ 的边 这样所有狼和羊之间的边都被割掉了 统计最小割就好辣 #i ...

  2. 洛谷 P2598 [ZJOI2009]狼和羊的故事 解题报告

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

  3. P2598 [ZJOI2009]狼和羊的故事(最小割)

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

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

    P2598 [ZJOI2009]狼和羊的故事 说真的,要多练练网络流的题了,这么简单的网络流就看不出来... 题目要求我们要求将狼和羊分开,也就是最小割,(等等什么逻辑...头大....) 我们这样想 ...

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

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

  6. 洛谷 P2598 [ZJOI2009]狼和羊的故事

    题目描述 “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈 ...

  7. 洛谷P2598 [ZJOI2009]狼和羊的故事

    题目描述 “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈 ...

  8. p2598 [ZJOI2009]狼和羊的故事

    传送门 分析 起点向狼连边,羊向终点连边,边权均为inf 每个点向它四联通的点连边权萎1的边 跑最小割即可 代码 #include<iostream> #include<cstdio ...

  9. 洛谷$P2598\ [ZJOI2009]$狼和羊的故事 网络流

    正解:网络流 解题报告: 传送门! 昂显然考虑最小割鸭$QwQ$,就考虑说每个土地要么属于羊要么属于狼,然后如果一条边上是栅栏一定是相邻两边所属不同. 所以考虑给所有羊向$S$连$inf$,所有狼向$ ...

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

    题目戳我 \(\text{Solution:}\) 显然思路,把所有羊看成一个源点,所有狼看成一个汇点,格子之间连容量为\(1\)的边,直接跑最小割. 技巧: 注意到篱笆不能把羊给割掉,狼同理.所以, ...

随机推荐

  1. ADAS芯片解决方案汇总

    ADAS(高级辅助驾驶系统),是指利用安装于车上各式各样的传感器,在第一时间收集车内的环境数据,进行静.动态物体的辨识.侦测与追踪等技术上的处理,从而能够让驾驶者在最快的时间察觉可能发生的危险. 在过 ...

  2. Scrum立会报告+燃尽图(十一月二十一日总第二十九次):β阶段第二周分配任务

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...

  3. Beta阶段第2周/共2周 Scrum立会报告+燃尽图 02

    此作业要求参见:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2410] 版本控制地址   https://git.coding.net ...

  4. C++的反思与总结

    博客作业学到的东西: 1.博客作业应该说是从寒假就开始了,因为博客作业,所以我寒假时都不敢玩得太疯狂,毕竟还有博客作业没做呢.有了博客作业,我就从一个连博客是什么都不知道无知少年,开始去了解博客是什么 ...

  5. 404 Note Found -(课堂实战)- 项目UML设计(团队)

    目录 团队信息 分工选择 课上分工 课下分工 ToDolist alpha版本要做的事情 燃尽图 UML 用例图 状态图 活动图 类图 部署图 实例图 对象图 时序图 包图 通信图 贡献分评定 课上贡 ...

  6. 周总结web未完成的代码

    <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Con ...

  7. ipv6问题

    1)百度搜索:针对苹果最新审核要求为应用兼容IPv6 2) ipV6测试网址:http://test-ipv6.com/ http://ipv6.jmu.edu.cn/ http://ipv6test ...

  8. jdbc 5.0

    1.事务 事务将单个SQL语句或一组SQL语句视为一个逻辑单元,如果任何语句失败,整个事务将失败. jdbc的MySQL驱动程序中的事务默认是自动提交. 默认情况下,每个SQL语句在完成后都会提交到数 ...

  9. 4th 课堂SCRM会议旁观记录

    项目名称:基于C#的连连看设计 小组名称:待定 小组成员:张政.张金生.武志远.李权 Master:张政 项目已完成部分: 现阶段已经实现了一定的功能,可以运行使用,进行第一关的游戏. 今天计划要完成 ...

  10. 【转载】mysql建表date类型不能设置默认值

    如题,mysql建表date类型的不能设置一个默认值,比如我这样: CREATE TABLE `new_table` ( `biryhday` datetime NULL DEFAULT '1996- ...