【BZOJ】1001: [BeiJing2006]狼抓兔子 Dinic算法求解平面图对偶图-最小割
1001: [BeiJing2006]狼抓兔子
Description
左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下 三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下角(N,M)的窝中去,狼王开始伏击这些兔子.当然 为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔 子一网打尽的前提下,参与的狼的数量要最小。因为狼还要去找喜羊羊麻烦.
Input
第一 行为N,M.表示网格的大小,N,M均小于等于1000.接下来分三部分第一部分共N行,每行M-1个数,表示横向道路的权值. 第二部分共N-1行,每行M个数,表示纵向道路的权值. 第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 输入文件保证不超过10M
Output
输出一个整数,表示参与伏击的狼的最小数量.
Sample Input
5 6 4
4 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6
Sample Output
讲讲Dinic算法:(Dinic算法属于最短增广路中的一种)
层次图:每次在残量网络中BFS得到每点到起点的距离;路径是在层次中找的,即d[v] == d[x]+1;比EK算法更高效
优化1:在DFS里面并不是每次只走一条路径,而是DFS到一条最短路之后,在回溯到不含最短边继续搜索;在DFS里面a表示目前为止所有弧的最小残量;而f表示路径的流量;即f<=a;根据a -= f是否等于0来判断是在当前节点几次上继续搜索还是回溯;
优化2:因为一个点可能会被多次搜索到,所以记录下前面搜索到该节点的那条边的序号,这样就不会从头开始搜索了;
ps:图中是无向边,我竟然还是建了反向边cap为0的图,真是醉了;JMJST使用Djistra+heap只用了516ms;我也重写了一个对偶图版本的,348ms~~详见 平面图最小割 对偶图
#include<iostream> #include<cstdio> #include<cstring> #include<string.h> #include<algorithm> #include<map> #include<queue> #include<vector> #include<cmath> #include<stdlib.h> #include<time.h> #include<stack> #include<set> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS1(a) memset(a,-1,sizeof(a)) #define inf 0x3f3f3f3f template<typename T> void read1(T &m) {T x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}m = x*f; } template<typename T> void read2(T &a,T &b){read1(a);read1(b);} template<typename T> void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);} template<typename T> void out(T a) {if(a>9) out(a/10);putchar(a%10+'0'); } const int M = 1000*1010; int head[M*6],tot; struct edge{int from,to,cap,flow,Next; }e[M*6]; void ins(int u,int v,int cap) {e[tot].Next = head[u];e[tot].from = u;//为了t->s时由v推到u;e[tot].to = v;e[tot].cap = cap;e[tot].flow = 0;head[u] = tot++; } int vis[M],s,t,cur[M],d[M]; queue<int> Q; int BFS() {rep1(i,s,t) vis[i] = 0;vis[s] = 1;d[s] = 0;Q.push(s);while(!Q.empty()){int u = Q.front();Q.pop();for(int i = head[u];~i;i = e[i].Next){int v = e[i].to;if(!vis[v] && e[i].cap > e[i].flow){ // 只考虑残量网络的弧 vis[v] = 1;d[v] = d[u] + 1;Q.push(v);}}}return vis[t]; } int DFS(int x,int a)// a表示目前为止所有弧的最小残量 {if(x == t || a == 0) return a;int& i = cur[x];//回溯时会多次DFS到同一个点if(i == 0) i = head[x];int flow = 0, f;for(;~i;i = e[i].Next){// 从上次考虑的弧开始int v = e[i].to;if(d[v] == d[x]+1 && (f = DFS(v,min(a,e[i].cap - e[i].flow))) > 0){e[i].flow += f;e[i^1].flow -= f;flow += f;a -= f;// 残量-流量if(a == 0) break;}}return flow; } int Dinic() {int flow = 0;while(BFS()){//仍然存在增广路时再DFSrep1(i,s,t) cur[i] = 0;//记录当前探索到的点的弧的编号flow += DFS(s,inf);}return flow; } void input() {int n,m,cost;read2(n,m);s = 0,t = n*m - 1;MS1(head);tot = 0;rep0(i,0,n){rep0(j,0,m-1){read1(cost);int u = i*m+j;ins(u,u+1,cost);ins(u+1,u,cost);}}rep0(i,0,n-1){rep0(j,0,m){read1(cost);int u = i*m+j,v = u + m;ins(u,v,cost);ins(v,u,cost);}}rep0(i,0,n-1){rep0(j,0,m-1){read1(cost);int u = i*m+j,v = u + m + 1;ins(u,v,cost);ins(v,u,cost);//无向边 }} } int main() {//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout); input();out(Dinic());return 0; }
View Code
转载于:https://www.cnblogs.com/hxer/p/5187633.html
【BZOJ】1001: [BeiJing2006]狼抓兔子 Dinic算法求解平面图对偶图-最小割相关推荐
- BZOJ 1001: [BeiJing2006]狼抓兔子【最大流/SPFA+最小割,多解】
1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MB Submit: 23822 Solved: 6012 [Submit ...
- bzoj 1001: [BeiJing2006]狼抓兔子
Time Limit: 15 Sec Memory Limit: 162 MB Submit: 21007 Solved: 5251 [Submit][Status][Discuss] Descr ...
- BZOJ 1001[BeiJing2006]狼抓兔子 最小割转最短路
Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一 ...
- 1001: [BeiJing2006]狼抓兔子(对偶图)
1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MB Submit: 23595 Solved: 5940 Descrip ...
- 1001: [BeiJing2006]狼抓兔子
/**************************************************************Problem: 1001User: whymheLanguage: C+ ...
- 对偶图 【BZOJ】1001: [BeiJing2006]狼抓兔子(对偶图+最短路)
http://www.lydsy.com/JudgeOnline/problem.php?id=1001 可谓惨不忍睹,一下午就在调这题了. 很久以前看到这题是一眼最大流,看到n<=1000,我 ...
- 【BZOJ - 1001】狼抓兔子(无向图网络流,最小割,或平面图转对偶图求最短路SPFA)
题干: 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...
- 【bzoj 1001】狼抓兔子
Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个 ...
- BZOJ1001[BeiJing2006]狼抓兔子——最小割
题目描述 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...
- 1001. [BJOI2006]狼抓兔子【最小割】
Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一 ...
最新文章
- redchat怎么编写shell脚本_shell脚本编写思路
- 爬取王垠的博客并生成pdf
- 左右声道测试音频_关于制作左右声道音频的剪辑软件推荐
- Unity 中的协同程序
- python从入门到精通学习笔记_Python从入门到精通之基础概念
- C/C++中extern的用法 ?
- Vim 安装 YouCompleteMe
- openssh升级_Redhat 6.5源码编译升级openssh到7.8版本
- openwrt打印机支持列表_共享打印机的三种安装连接方法
- Adams2019安装教程链接分享
- 【STM32】RCC复位和时钟控制器
- 计算机日志文件事件ID,教程分享:如何在Windows上对用户配置文件服务事件ID进行故障排除!...
- Room使用遇到的问题
- Pytorch搭建ResNet网络进行垃圾分类
- 【博客431】接入层 汇聚层 核心层
- Excel 撤消工作表保护密码
- 计算机专业如何写毕业论文-八大技巧
- javascript中的jQuery简单应用
- 基于Python 3.11.0版本模拟登录并爬取西安理工大学正方教务系统的学分绩点并计算
- 物联网云平台的优势有哪些
热门文章
- 未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序报错的解决办法
- bzoj 1800 [Ahoi2009]fly 飞行棋——模拟
- 【codeforces 534B】Covered Path
- 网络流 增广路 入门很好的文章
- [原创]markdown语法学习(commonmark)
- oracle 导入DMP数据 imp 10g
- 牛客练习赛9 F - 珂朵莉的约数
- 三天学会HTML5——SVG和Canvas的使用
- 【JAVA笔记——道】Hadoop设计模式--抽象类
- 搭建完全分布式的hadoop[转]