【图论专题二】【网络流部分】狼和羊的故事
【浙江省省选2009】狼和羊的故事
题目
【ZJOI2009】狼和羊的故事 (Standard IO)
Time Limits: 1000 ms Memory Limits: 256000 KB Detailed Limits
Description
“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......”
Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干!
Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。
通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。
Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。
Input
输入数据存放在文本文件ws.in中。
文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。
Output
输出数据存放在文本文件ws.out中。
文件中仅包含一个整数ans,代表篱笆的最短长度。
Sample Input
2 2
2 2
1 1
Sample Output
2
Data Constraint
Hint
【数据范围】
10%的数据 n,m≤3
30%的数据 n,m≤20
100%的数据 n,m≤100
题解
一眼看,这道题还以为是计算几何。并且直接贪心即可。抱着将信将疑的态度打了一个对拍,发现有一个棘手的“0”。这个“0”会使答案很难计算。我们发现,这个空地要么是属于狼的,要么是属于羊的领地。所以我们可以考虑最小割。基本思路就是,设S为羊的领地,T为狼的领地。如果割得离S近,代表这个"0"属于羊的领地,否则反之,然后跑一遍最小割最大流。
正解
我想不到其他方法了。故只有一种方法。
建一个原点S表示羊的领地;T点表示狼的领地。原先就属于羊的领地就朝S点连一条边权为无限大的边;原先属于狼的领地就朝T点同理。中间不确定的点就落在中间。将相邻的点连起来,边权为1。然后直接跑一遍最小割,就是答案。
你可以试这证明一下……
证明
首先,无限大的边保证了原先属于狼与羊的领地不会发生改变。而且,肯定会割掉中间那些关于篱笆的边;对于不定项的点,如果割去左边的边,那么就肯定是归属于羊了,否则反之。
代码
#include<cstdio>
#include<cstring>
#define N 101
#define M 101
using namespace std;
int total1,S,T,n,m;
int fx[5]={0,0,1,0,-1};
int fy[5]={0,1,0,-1,0};
int h[N*M*6],dis[N*M+2],head[N*M*6],next[N*M*6],edge[N*M*6],v[N*M*6];
int a[N][M];
void insert(int x,int y,int z)
{total1++;next[total1]=head[x];head[x]=total1;edge[total1]=y;v[total1]=z;
}
bool bfs()
{memset(dis,0,sizeof(dis));int l=1,r=1;h[1]=S;dis[S]=1;while (l<=r){int u=h[l];for (int i=head[u];i;i=next[i]){int y=edge[i];if (v[i]>0&&dis[y]==0){r++;h[r]=y;dis[y]=dis[u]+1;if (y==T) return true;}}l++;}return false;
}
int dinic(int k,int flow)
{if (k==T) return flow;int rest=flow;for (int i=head[k];i;i=next[i]){int y=edge[i];if (v[i]>0&&dis[y]==dis[k]+1){int cost;if (rest>v[i]) cost=v[i];else cost=rest;int get=dinic(y,cost);if (get==0) dis[y]=0;rest-=get;v[i]-=get;v[i^1]+=get;if (rest==0) break;}}return flow-rest;
}
int main()
{scanf("%d%d",&n,&m);total1=1;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]==2){insert(T,(i-1)*m+j,0);insert((i-1)*m+j,T,999999);//printf("%d %d %d\n",(i-1)*m+j,T,999999); } if (a[i][j]==1){insert((i-1)*m+j,S,0);insert(S,(i-1)*m+j,999999);//printf("%d %d %d\n",S,(i-1)*m+j,999999); }for (int k=1;k<=4;k++){int xx=i+fx[k];int yy=j+fy[k];if (xx>0&&yy>0&&xx<=n&&yy<=m){if (a[i][j]==1){if (a[xx][yy]!=a[i][j]){insert((i-1)*m+j,(xx-1)*m+yy,1);insert((xx-1)*m+yy,(i-1)*m+j,0);} } if (a[i][j]==0){if (a[xx][yy]!=1){insert((i-1)*m+j,(xx-1)*m+yy,1);insert((xx-1)*m+yy,(i-1)*m+j,0);}}}}}}//printf("%d\n",(total1-1)/2);int maxflow=0;int flow;while (bfs())while (flow=dinic(S,999999)) maxflow+=flow;printf("%d",maxflow);
}
【图论专题二】【网络流部分】狼和羊的故事相关推荐
- 图论专题1(网络流)
推荐阅读: 网络流基础知识和Dinic:http://www.cnblogs.com/SYCstudio/p/7260613.html#3848907 建模:https://www.cnblogs.c ...
- BZOJ1412 ZJOI2009 狼和羊的故事 【网络流-最小割】
BZOJ1412 ZJOI2009 狼和羊的故事 Description "狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......" Orez听 ...
- 【BZOJ1412】【ZJOI2009】狼和羊的故事(网络流)
Description "狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向--" Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说 ...
- bzoj1412[ZJOI2009]狼和羊的故事
bzoj1412[ZJOI2009]狼和羊的故事 题意: n*m网格,每个格子可能为狼.羊或空格.现在要在一些格子边界篱笆使羊狼分开,求最短篱笆.n,m≤100 题解: 最小割问题,建一个超级源和超级 ...
- 题解 P2598 【[ZJOI2009]狼和羊的故事】
P2598 [ZJOI2009]狼和羊的故事 题目描述 "狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......" Orez听到这首歌,心想:狼 ...
- [ZJOI2009]狼和羊的故事 题解
狼和羊的故事 怎么说呢,这道题其实不难,只是题意有那么亿点点难理解.我最开始想复杂了,理解为了栅栏长度是格点的周长,那事情就复杂了... 题目分析: 首先,要明确的是:一个狼领地和羊领地之间只需建长度 ...
- [ZJOI2009]狼和羊的故事【最小割】
题目链接 P2598 [ZJOI2009]狼和羊的故事 要让羊和狼都区别开来,需要的最小的割是多少?每只羊向四周有4个可能的方向,每只狼也是同样的,所以每个动物向周围可以跑出4个流,我们要建立栅栏,可 ...
- BZOJ 1412: [ZJOI2009]狼和羊的故事
1412: [ZJOI2009]狼和羊的故事 >原题链接< Description "狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......& ...
- [bzoj1934]: [ZJOI2009]狼和羊的故事
1412: [ZJOI2009]狼和羊的故事 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3105 Solved: 1567 [Submit][ ...
最新文章
- HTML5中的localStorage用法
- HDU2045 不容易系列之(3)—— LELE的RPG难题(递推)
- IDEA 重复代码快速重构
- 数据结构与算法 / 字符串匹配 / Trie 树
- Linux环境变量中PS1
- 一条SQL更新语句是如何执行的?
- c++输入了后边不继续_医疗:连涨多日,后边还能加仓吗?直接说答案!
- 关于C/C++中的“auto”关键字
- php 登录安全认证,介绍几种常用的web安全认证方式
- Python笔记-BeautifulSoup通过查找Id获取元素信息
- 美团暑期实习前端面试
- java速学堂_Java 实例 - 状态监测
- 一次搭建Spark集群(standalone、yarn、高可用)
- 液晶接口系列——MIPI(三)DSI时序讲解与实际测试
- Zlib文件压缩和解压
- 兜了一圈,发现想要的APK在这里有
- 周志华 《机器学习》之 第十二章(计算学习理论)概念总结
- jbox弹窗_Jquery多功能提示通知弹出对话框插件jBox中文文档
- #榜样的力量#航班管家全球大交通出行疫情追踪服务系统丨数据猿新冠战“疫”公益策划...
- win10关闭未格式化U盘插入提示格式化弹窗
热门文章
- MATLAB语言的串口助手
- 【转】windows下使用netstat统计tcp、ip、端口的数量统计
- vue里面的ref详解
- echarts数据可视化项目经验积累
- python画大象_Python Day21
- 大数据导论习题_2020智慧树答案 大数据概论 最新知到章节测试答案
- 郑莉java课后答案,Java语言程序设计(郑莉)第三章课后习题答案
- Google earth中的jpg格式转成论文需要的固定宽度tiff格式的方法
- centos系统安装中文字体几种方法
- java 输入五种水果_java--IO和面向对象(简单的水果仓库管理系统--可选择操作)...