BZOJ1001 BJOI2006 狼抓兔子

Description


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

左上角点为(1,1),右下角点为(N,M)(上图中N=3,M=4).有以下三种类型的道路

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个数,表示斜向道路的权值.

Output:

输出一个整数,表示参与伏击的狼的最小数量.

Solution

转化为网络流,把每个有直接连边的点之间连一条权为X的边,然后跑一边最大流即可。

 1 //Writer : Hsz %WJMZBMR%tourist%hzwer
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 #include<set>
 9 #include<stack>
10 #include<vector>
11 #include<cstdlib>
12 #include<algorithm>
13 #define LL long long
14 using namespace std;
15 const int S=1,N=1000001,M=6000001,inf=0x3fffffff;
16 int to[M],val[M],nxt[M],h[N],head[N],ecnt=1,T;
17 int n,m;
18 void add(int bg,int ed,int v) {
19     to[++ecnt]=ed;
20     nxt[ecnt]=head[bg];
21     val[ecnt]=v;
22     head[bg]=ecnt;
23 }
24 void ins(int bg,int ed,int x) {
25     add(bg,ed,x);
26     add(ed,bg,x);
27 }
28 bool bfs() {
29     memset(h,-1,sizeof h);
30     h[S]=0;
31     queue<int>q;
32     q.push(S);
33     while(!q.empty()) {
34         int u=q.front();
35         q.pop();
36         for(int i=head[u]; i; i=nxt[i]) {
37             if(val[i]&&h[to[i]]==-1) {
38                 h[to[i]]=h[u]+1;
39                 q.push(to[i]);
40             }
41         }
42     }
43     return h[T]!=-1;
44 }
45 int dfs(int x,int f) {
46     if(x==T) return f;
47     int tp,used=0;
48     for(int i=head[x]; i; i=nxt[i]) {
49         if(h[to[i]]==h[x]+1&&val[i]) {
50             tp=dfs(to[i],min(f-used,val[i]));
51             val[i]-=tp;
52             val[i^1]+=tp;
53             used+=tp;
54             if(used==f) return f;
55         }
56     }
57     if(!used ) h[x]=-1;
58     return used;
59 }
60 int maxflow;
61 void dinic() {
62     maxflow=0;
63     while(bfs()) {
64         maxflow+=dfs(1,inf);
65     }
66 }
67 int main() {
68     int x;
69     cin>>n>>m;
70     T=n*m;
71     for(int i=1; i<=n; i++) {
72         for(int j=1; j<m; j++) {
73             scanf("%d",&x);
74             ins(m*(i-1)+j,m*(i-1)+j+1,x);//建图过程。加的反边也应权为x,因为反向也可能跑兔子。
75         }
76     }
77     for(int i=1; i<n; i++) {
78         for(int j=1; j<=m; j++) {
79             scanf("%d",&x);
80             ins(m*(i-1)+j,m*(i)+j,x);
81         }
82     }
83     for(int i=1; i<n; i++) {
84         for(int j=1; j<m; j++) {
85             scanf("%d",&x);
86             ins(m*(i-1)+j,m*(i)+j+1,x);
87         }
88     }
89     dinic();
90     cout<<maxflow;
91     return 0;
92 }

原文地址:https://www.cnblogs.com/sdfzhsz/p/9005961.html

时间: 2024-10-07 13:43:40

BZOJ1001 BJOI2006 狼抓兔子的相关文章

BJOI2006狼抓兔子

1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 9967  Solved: 2267[Submit][Status] Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:  左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类

[BJOI2006]狼抓兔子 暴力AC啦!

直接暴力建边,在lougu上跑的飞快.(except the last test) 总结一下也就是三句话: insert(id(i, j), id(i, j + 1), x) insert(id(i, j), id(i + 1, j), x) insert(id(i, j), id(i + 1, j + 1), x) 没了就,..dinic什么的就看看本博客分享的总结爸... 代码当然还是要发的,即使只是一个暴力.. 1 #include <map> 2 #include <set>

bzoj1001 [BeiJing2006]狼抓兔子

1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 23723  Solved: 5981[Submit][Status][Discuss] Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M

BZOJ1001: [BeiJing2006]狼抓兔子【最短路】

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1001 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 27684  Solved: 7127 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的

[BZOJ1001] [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) 道路上的权值表示这条路上最多能够通过的兔子数,道路是

[bzoj1001][BeiJing2006]狼抓兔子-题解[平面图最小割转最短路]/[Dinic求最小割]

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) 道路上的权值表示这条路上最多能够通过的兔子数,道路

[BJOI2006]狼抓兔子(网络流)

题目描述 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=3,M=4).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上

[BJOI2006]狼抓兔子

思路: 求网格图的最小割.然而网格图的边数比较多,直接用EdmondsKarp算法会TLE(据说用Dinic或ISAP可以过),解决的方法是将网格图的最小割转化成其对偶图的最短路,设图的左下端为起点,右上端为重点,然后跑一遍Dijkstra即可.注意要特判$n=1$或$m=1$的情况,另外因为每个方格实际上是会被斜线分成两个三角,所以点数要开两倍$n^2$,也就是$2\times10^6$. 1 #include<cstdio> 2 #include<cctype> 3 #incl

BZOJ1001[BeiJing2006]狼抓兔子(无向图最小割)

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 这题的题意其实就是求一个最小割,但是由于是无向图,所以加边的时候,两边的流量都要是输入的权值,然后就是一个dinic求一下最小割. 但是这题貌似有很高超的技巧来搞,可以把平面图上的最小割转成对偶图上的最短路来做,这样可以起到很明显的优化效果.现在还不是很明白,如果以后明白了,会再来更新. dinic: #include <cstdio> #include <cstring&g