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

3 4

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

14

HINT

2015.4.16新加数据一组,可能会卡掉从前可以过的程序。

题解:

这题就是一个最小割最大流定理应用的模板题,最后跑个最大流就好了...我这里用的Dinic算法,其精髓就是dfs可多条路同时增广,一开始用vector谜之爆内存,所以改为前向星。

注意一下当前弧优化,很有用的一个优化。

代码如下:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <iostream>
  5. #include <vector>
  6. #include <queue>
  7. #define INF 0x3f3f3f
  8. using namespace std;
  9.  
  10. const int N = ,M = ;
  11. struct Edge{
  12. int v,c,next;
  13. }e[M];
  14. int head[N],d[N],cur[N];
  15. int n,m,tot=;
  16. void adde(int u,int v,int w){
  17. e[tot].v=v;e[tot].c=w;e[tot].next=head[u];head[u]=tot++;
  18. e[tot].v=u;e[tot].c=w;e[tot].next=head[v];head[v]=tot++;
  19. }
  20. bool bfs(int s,int t){
  21. queue<int> q;
  22. memset(d,,sizeof(d));d[s]=;
  23. q.push(s);
  24. while(!q.empty()){
  25. int u=q.front();q.pop();
  26. for(int i=head[u];i!=-;i=e[i].next){
  27. int v=e[i].v;
  28. if(!d[v] && e[i].c>){
  29. d[v]=d[u]+;
  30. q.push(v);
  31. }
  32. }
  33. }
  34. return d[t]!=;
  35. }
  36. int dfs(int s,int a){
  37. if(s==n*m || a==) return a;
  38. int flow=,f;
  39. for(int &i=cur[s];i!=-;i=e[i].next){
  40. int v=e[i].v;
  41. if(d[v]!=d[s]+) continue ;
  42. f=dfs(v,min(a,e[i].c));
  43. if(f>){
  44. e[i].c-=f;
  45. e[i^].c+=f;
  46. flow+=f;
  47. a-=f;
  48. if(a==) break;
  49. }
  50. }
  51. if(!flow) d[s]=-;
  52. return flow;
  53. }
  54. int Dinic(){
  55. int ans = ;
  56. while(bfs(,n*m)){
  57. for(int i=;i<=n*m;i++) cur[i]=head[i];
  58. ans+=dfs(,INF);
  59. }
  60. return ans;
  61. }
  62. int main(){
  63. scanf("%d%d",&n,&m);
  64. int w;
  65. memset(head,-,sizeof(head));
  66. for(int i=;i<=n;i++){
  67. for(int j=;j<=m-;j++){
  68. scanf("%d",&w);
  69. adde(m*(i-)+j,m*(i-)+j+,w);
  70. }
  71. }
  72. for(int i=;i<=n-;i++){
  73. for(int j=;j<=m;j++){
  74. scanf("%d",&w);
  75. adde(j+(i-)*m,j+i*m,w);
  76. }
  77. }
  78. for(int i=;i<=n-;i++){
  79. for(int j=;j<=m-;j++){
  80. scanf("%d",&w);
  81. adde((i-)*m+j,i*m+j+,w);
  82. }
  83. }
  84. cout<<Dinic();
  85. return ;
  86. }

vector写了也不能白写,附上模板吧...

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <iostream>
  5. #include <vector>
  6. #include <queue>
  7. #define INF 0x3f3f3f
  8. using namespace std;
  9.  
  10. const int N = ;
  11.  
  12. struct Edge{
  13. int u,v,flow,c;
  14. };
  15.  
  16. vector <int > vec[N];
  17. vector <Edge> edges;
  18. int n,m;
  19. int cur[N],d[N];
  20.  
  21. void adde(int u,int v,int w){
  22. edges.push_back((Edge){u,v,,w});
  23. edges.push_back((Edge){v,u,,w});
  24. int m = edges.size();
  25. vec[u].push_back(m-);
  26. vec[v].push_back(m-);
  27. }
  28. bool bfs(int s,int t){
  29. memset(d,,sizeof(d));d[s]=;
  30. queue <int> q;
  31. q.push(s);
  32. while(!q.empty()){
  33. int u = q.front();q.pop();
  34. for(int i=;i<vec[u].size();i++){
  35. Edge& E = edges[vec[u][i]];
  36. if(!d[E.v] && E.c>E.flow){
  37. q.push(E.v);
  38. d[E.v]=d[u]+;
  39. }
  40. }
  41. }
  42. if(!d[t]) return false;
  43. return true ;
  44. }
  45. int dfs(int s,int a){ //a 目前最小残量
  46. if(s==n*m || a==) return a;
  47. int flow=,f;
  48. for(int& i=cur[s];i<vec[s].size();i++){
  49. Edge &E = edges[vec[s][i]];
  50. if(d[E.v]!=d[s]+) continue ;
  51. f=dfs(E.v,min(E.c-E.flow,a));
  52. if(f>){
  53. edges[vec[s][i]].c-=f;
  54. edges[vec[s][i]^].c+=f;
  55. a-=f;
  56. flow+=f;
  57. if(a==) break ;
  58. }
  59. }
  60. return flow;
  61. }
  62. int Dinic(){
  63. int ans = ;
  64. while(bfs(,n*m)){
  65. memset(cur,,sizeof(cur));
  66. ans+=dfs(,INF);
  67. }
  68. return ans ;
  69. }

BZOJ1001:狼抓兔子(最小割最大流+vector模板)的更多相关文章

  1. [bzoj1001]狼抓兔子 最小割

    题意概述:给出一张无向图,每条边有一个权值,割掉这条边代价为它的权值,求使起点不能到达终点的最小代价. 显然能看出这是个最小割嘛,然后最小割=最大流,建图的时候特殊处理一下再跑个最大流就好了. #in ...

  2. [BJOI2006][bzoj1001] 狼抓兔子 [最小割]

    题面: 传送门 思路: 其实就是一道最小割的题目...... 我的写法加了两个优化,常数比较小,所以过掉了 一个是当前弧,一个是若当前点并不能流出去,那么标记dep为-1 听说正解是对偶图最短路?可以 ...

  3. BZOJ1001: [BeiJing2006]狼抓兔子 [最小割 | 对偶图+spfa]

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 19528  Solved: 4818[Submit][ ...

  4. bzoj1001: [BeiJing2006]狼抓兔子 -- 最小割

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MB Description 现在小朋友们最喜欢的"喜羊羊与灰太狼 ...

  5. BZOJ 1001 狼抓兔子 (最小割转化成最短路)

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 27715  Solved: 7134[Submit][ ...

  6. BZOJ1001[BeiJing2006]狼抓兔子最小割網絡流

    Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一 ...

  7. BZOJ1001[BeiJing2006]狼抓兔子——最小割

    题目描述 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...

  8. 【bzoj1001】[BeiJing2006]狼抓兔子 最小割+对偶图+最短路

    题目描述 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...

  9. BZOJ1001 [BeiJing2006]狼抓兔子 最小割 对偶图 最短路

    原文链接http://www.cnblogs.com/zhouzhendong/p/8686871.html 题目传送门 - BZOJ1001 题意 长成上面那样的网格图求最小割. $n,m\leq ...

随机推荐

  1. 腾讯招聘网数据爬取存入mongodb

    #!/user/bin/env python3 # -*- coding: utf-8 -*- import requests from lxml import etree from math imp ...

  2. 自定义vim配置文件vimrc,用于c/c++编程

    vim作为Linux下广受赞誉的代码编辑器,其独特的纯命令行操作模式可以很大程度上方便编程工作,通过自定义vim配置文件可以实现对vim功能的个性化设置. vim配置文件一般有两份,属于root的/e ...

  3. stm32+lwip(五):以太网帧发送测试

    我是卓波,很高兴你来看我的博客. 系列文章: stm32+lwip(一):使用STM32CubeMX生成项目 stm32+lwip(二):UDP测试 stm32+lwip(三):TCP测试 stm32 ...

  4. centos 7 关闭IPtables

    systemctl status iptables.service systemctl stopiptables.service

  5. 牛客网暑期ACM多校训练营(第四场) F

    参考:http://www.cnblogs.com/Jadon97/p/9383027.html #include <iostream> #include <cstdio> # ...

  6. js数组长度

    js数组长度,一般使用length 属性即可获取,但这个数组是个对象则只能使用以下方式 var t=typeof o; var length=0; if(t=='string'){ length=o. ...

  7. python2.7练习小例子(六)

        6):题目:斐波那契数列.     程序分析:斐波那契数列(Fibonacci sequence),又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.……. ...

  8. kudu是什么

    Apache Kudu Overview 建议配合[Apache Kudo]审阅本文(http://kudu.apache.org/overview.html) 数据模式 Kudo是一个列式存储的用于 ...

  9. 20145202马超《网络对抗》Exp3免杀 进阶

    木马化正常软件,如通过改变机器指令.实现可免杀免防火墙提示的后门. 继上次实验3所做的代码在主函数里面加上一行调用就可以 改各种属性,这里我参考了郝浩同学的博客 最后我还是遇到了问题 后来发现虽然有那 ...

  10. LeetCode 29——两数相除

    1. 题目 2. 解答 2.1. 方法一 题目要求不能使用乘法.除法和除余运算,但我们可以将除法转移到对数域. \[ \frac{a}{b} = e^{\frac{lna}{lnb}} = e^{ln ...