1001: [BeiJing2006]狼抓兔子

Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 19528  Solved: 4818
[Submit][Status][Discuss]

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新加数据一组,可能会卡掉从前可以过的程序。


就是用狼把这个图割开
或者想最多兔子量,然后一个兔子一个狼
 
法1:dinic
注意这是无向图

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. const int N=1e6+,INF=1e9;
  7. inline int read(){
  8. char c=getchar();int x=,f=;
  9. while(c<''||c>''){if(c=='-')f=-;c=getchar();}
  10. while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
  11. return x*f;
  12. }
  13. int n,m,c,s,t;
  14. struct edge{
  15. int v,ne,c,f;
  16. }e[N*];
  17. int cnt,h[N];
  18. inline void ins(int u,int v,int c){//printf("ins %d %d %d\n",u,v,c);
  19. cnt++;
  20. e[cnt].v=v;e[cnt].c=c;e[cnt].f=;e[cnt].ne=h[u];h[u]=cnt;
  21. cnt++;
  22. e[cnt].v=u;e[cnt].c=c;e[cnt].f=;e[cnt].ne=h[v];h[v]=cnt;
  23. }
  24. inline int id(int i,int j){return (i-)*m+j;}
  25. int vis[N],d[N],q[N],head,tail;
  26. inline void lop(int &x){if(x==N)x=;}
  27. bool bfs(){
  28. memset(vis,,sizeof(vis));
  29. memset(d,,sizeof(d));
  30. head=tail=;
  31. q[tail++]=s;d[s]=;vis[s]=;
  32. while(head!=tail){
  33. int u=q[head++];lop(head);
  34. for(int i=h[u];i;i=e[i].ne){
  35. int v=e[i].v;
  36. if(!vis[v]&&e[i].c>e[i].f){
  37. vis[v]=;d[v]=d[u]+;
  38. q[tail++]=v;lop(tail);
  39. if(v==t) return true;
  40. }
  41. }
  42. }
  43. return false;
  44. }
  45. int cur[N];
  46. int dfs(int u,int a){
  47. if(u==t||a==) return a;
  48. int flow=,f;
  49. for(int &i=cur[u];i;i=e[i].ne){
  50. int v=e[i].v;
  51. if(d[v]==d[u]+&&(f=dfs(v,min(a,e[i].c-e[i].f)))>){
  52. flow+=f;
  53. e[i].f+=f;
  54. e[((i-)^)+].f-=f;
  55. a-=f;
  56. if(a==) break;
  57. }
  58. }
  59. return flow;
  60. }
  61. int dinic(){
  62. int flow=;
  63. while(bfs()){
  64. for(int i=s;i<=t;i++) cur[i]=h[i];
  65. flow+=dfs(s,INF);//printf("dinic %d\n",flow);
  66. }
  67. return flow;
  68. }
  69. int main(){
  70. n=read();m=read();s=id(,);t=n*m;
  71. for(int i=;i<=n;i++)
  72. for(int j=;j<=m-;j++){c=read();ins(id(i,j),id(i,j+),c);}
  73. for(int i=;i<=n-;i++)
  74. for(int j=;j<=m;j++) {c=read();ins(id(i,j),id(i+,j),c);}
  75. for(int i=;i<=n-;i++)
  76. for(int j=;j<=m-;j++){c=read();ins(id(i,j),id(i+,j+),c);}
  77. int ans=dinic();
  78. printf("%d",ans);
  79. }
法2:对偶图+spfa

浅析最大最小定理在信息学竞赛中的应用

对于平面图,对偶图的最短路就是原图的最小割

直接想也容易理解,最短路就是把一些边割了

想的时候可以加一条s*到t*的INF的边把s*和t*面割开,但是程序不要加,否则暴增3000ms

1116ms,dinic用了1684ms

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. const int N=2e6+,INF=1e9;
  7. inline int read(){
  8. char c=getchar();int x=,f=;
  9. while(c<''||c>''){if(c=='-')f=-;c=getchar();}
  10. while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
  11. return x*f;
  12. }
  13. int n,m,c,s,t;
  14. struct edge{
  15. int v,ne,w;
  16. }e[N*];
  17. int h[N],cnt=;
  18. inline void ins(int u,int v,int w){//printf("ins %d %d %d\n",u,v,w);
  19. cnt++;
  20. e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
  21. cnt++;
  22. e[cnt].v=u;e[cnt].w=w;e[cnt].ne=h[v];h[v]=cnt;
  23. }
  24. inline void lop(int &x){if(x==N) x=;else if(x==) x=N-;}
  25. int d[N],q[N],head,tail;bool inq[N];
  26. int spfa(){
  27. memset(d,,sizeof(d));
  28. head=tail=;
  29. q[tail++]=s;inq[s]=;d[s]=;
  30. while(head!=tail){
  31. int u=q[head++];inq[u]=;lop(head);
  32. for(int i=h[u];i;i=e[i].ne){
  33. int v=e[i].v,w=e[i].w;
  34. if(d[v]>d[u]+w){
  35. d[v]=d[u]+w;
  36. if(!inq[v]){
  37. if(d[v]<d[q[head]]) head--,lop(head),q[head]=v;
  38. else q[tail++]=v,lop(tail);
  39. inq[v]=;
  40. }
  41. }
  42. }
  43. }
  44. return d[t];
  45. }
  46. int main(){
  47. n=read();m=read();
  48. int col=*(m-),row=n-;
  49. s=;t=col*row+;//ins(s,t,INF);
  50. for(int i=;i<=n;i++)
  51. for(int j=;j<=m-;j++){
  52. c=read();
  53. if(i==) ins(t,(j<<),c);
  54. else if(i==n) ins((i-)*col+(j<<)-,s,c);
  55. else ins((i-)*col+(j<<)-,(i-)*col+(j<<),c);
  56. }
  57.  
  58. for(int i=;i<=n-;i++)
  59. for(int j=;j<=m;j++){
  60. c=read();
  61. if(j==) ins(s,(i-)*col+,c);
  62. else if(j==m) ins((i-)*col+(j<<)-,t,c);
  63. else ins((i-)*col+(j<<)-,(i-)*col+(j<<)-,c);
  64. }
  65.  
  66. for(int i=;i<=n-;i++)
  67. for(int j=;j<=m-;j++){
  68. c=read();
  69. ins((i-)*col+(j<<)-,(i-)*col+(j<<),c);
  70. }
  71. int ans=spfa();
  72. printf("%d",ans);
  73. }
 
 

BZOJ1001: [BeiJing2006]狼抓兔子 [最小割 | 对偶图+spfa]的更多相关文章

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

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

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

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

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

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

  4. [bzoj 1001][Beijing2006]狼抓兔子 (最小割+对偶图+最短路)

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

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

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

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

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

  7. BZOJ1001: [BeiJing2006]狼抓兔子 (最小割转最短路)

    浅析最大最小定理在信息学竞赛中的应用---周东 ↑方法介绍 对于一个联通的平面图G(满足欧拉公式) 在s和t间新连一条边e; 然后建立一个原图的对偶图G*,G*中每一个点对应原图中每一个面,每一条边对 ...

  8. bzoj1001/luogu4001 狼抓兔子 (最小割/平面图最小割转对偶图最短路)

    平面图转对偶图:先在原图中加一个s->t的边,然后对每个面建一个点,对每条分隔两个面的边加一条连接这两个面对应点的边,边权等于原边权. 然后从刚才加的s->t分割出来的两面对应的两个点跑最 ...

  9. BZOJ 1001: [BeiJing2006]狼抓兔子 最小割

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓 ...

随机推荐

  1. EF架构~EF异步改造之路~仓储接口的改造

    回到目录 返回异步与并行目录 C#5.0带来了并行编程 {C#1.0托管代码→C#2.0泛型→C#3.0LINQ→C#4.0动态语言→C#5.0异步编程} 随着C#5.0在.net4.5出来之后,它们 ...

  2. SpringMVC中servletFileUpload.parseRequest(request)解析为空获取不到数据问题

    原因分析 首先我们来看下Spring mvc 中文件上传的配置 <bean id="multipartResolver" class="org.springfram ...

  3. python之消息队列

    引言 你是否遇到过两个(多个)系统间需要通过定时任务来同步某些数据?你是否在为异构系统的不同进程间相互调用.通讯的问题而苦恼.挣扎?如果是,那么恭喜你,消息服务让你可以很轻松地解决这些问题.消息服务擅 ...

  4. Spring声明事务管理

    首先我们先了解事务,什么是事务? 简单来说就是要么全部成功,要么什么都不做. 为什么要使用事务? 比如说常用银行系统的例子,如果没有用事务,有人在存入钱的时候出了问题,那么银行系统数据库的数据没有改变 ...

  5. js鼠标滚轮滚动图片切换效果

    效果体验网址:http://keleyi.com/keleyi/phtml/image/12.htm HTML文件代码: <!DOCTYPE html PUBLIC "-//W3C// ...

  6. HTML5学习笔记一 简单学习HTML5

    什么是HTML? HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言: HyperText Markup Language HTML 不是一种编程语言,而是一种标记语言 标记语言是一 ...

  7. Android 学习心得 页面跳转,不显示新页面信息

    原因: 1.新页面的Activity中,public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceSt ...

  8. openfire安装

    服务器第一次能够开启,但不久就断开,再连接就会闪退,命令行更改Java路径后即可 http://www.jianshu.com/p/5d88fe201c71 开启服务器后,导入数据库脚本,创建几个测试 ...

  9. Android中Listview点击item不变颜色以及设置listselector 无效

    Android中Listview点击item不变颜色以及设置listselector 无效 这是同一个问题,Listview中点击item是会变颜色的,因为listview设置了默认的listsele ...

  10. Android5.0 TimePicker,DatePicker恢复成低版本滚动模式

    新版中的TimePicker DatePicker是不支持使用遥控器的, 恢复成低版本滚动模式只需要是xml文件加上一句即可: android:datePickerMode="spinner ...