[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) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(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新加数据一组,可能会卡掉从前可以过的程序。

Solution

  乍一看是一道网络流的题,但是实际写完会发现超时超到姥姥家去了。

  定理:平面图的最大流=该图对偶图的最短路,某形象解释见某贴心神犇

  之后SPFA乱搞获Dijkstra乱搞,不过我建边的方式有点鬼畜。

  1 #include <cstdio>
  2 #include <cstring>
  3 using namespace std;
  4 struct node
  5 {
  6     int v, w;
  7 }edge[6000005];
  8 int fst[2000005], nxt[6000005], sss, ttt, dis[2000005], q[2000005], front, back;
  9 bool inq[2000005];
 10
 11 void qscanf(int &x)
 12 {
 13     char c = getchar();
 14     x = 0;
 15     while(c < ‘0‘ || c > ‘9‘)
 16         c = getchar();
 17     while(c >= ‘0‘ && c <= ‘9‘)
 18         x = x * 10 + c - ‘0‘, c = getchar();
 19 }
 20
 21 void addedge(int i, int u, int v, int w)
 22 {
 23     edge[i << 1] = (node){v, w}, nxt[i << 1] = fst[u], fst[u] = i << 1;
 24     edge[i << 1 | 1] = (node){u, w}, nxt[i << 1 | 1] = fst[v], fst[v] = i << 1 | 1;
 25 }
 26
 27 void SPFA()
 28 {
 29     memset(dis, 63, sizeof(dis));
 30     dis[sss] = 0, inq[sss] = q[++back] = sss;
 31     while(front != back)
 32     {
 33         int u = q[++front % 2000000];
 34         inq[u] = false, front %= 2000000;
 35         for(int i = fst[u]; i; i = nxt[i])
 36         {
 37             int v = edge[i].v, w = edge[i].w;
 38             if(dis[v] > dis[u] + w)
 39             {
 40                 dis[v] = dis[u] + w;
 41                 if(!inq[v])
 42                 {
 43                     dis[v] = dis[u] + w;
 44                     inq[v] = true;
 45                     q[++back % 2000000] = v;
 46                     back %= 2000000;
 47                 }
 48             }
 49         }
 50     }
 51 }
 52
 53 int main()
 54 {
 55     int n, m, etot = 0;
 56     qscanf(n), qscanf(m);
 57     n--, m--;
 58     if(n && m)
 59     {
 60         sss = n * m * 2 + 1, ttt = n * m * 2 + 2;
 61         for(int i = 1; i <= n + 1; i++)
 62             for(int j = 1; j <= m; j++)
 63             {
 64                 int u = ((i - 2) * m + j) * 2 - 1, v = ((i - 1) * m + j) * 2, w;
 65                 qscanf(w);
 66                 if(i == 1)
 67                     addedge(++etot, sss, v, w);
 68                 else if(i == n + 1)
 69                     addedge(++etot, u, ttt, w);
 70                 else
 71                     addedge(++etot, u, v, w);
 72             }
 73         for(int i = 1; i <= n; i++)
 74             for(int j = 1; j <= m + 1; j++)
 75             {
 76                 int u = ((i - 1) * m + j) * 2 - 2, v = ((i - 1) * m + j) * 2 - 1, w;
 77                 qscanf(w);
 78                 if(j == 1)
 79                     addedge(++etot, ttt, v, w);
 80                 else if(j == m + 1)
 81                     addedge(++etot, u, sss, w);
 82                 else
 83                     addedge(++etot, u, v, w);
 84             }
 85         for(int i = 1; i <= n; i++)
 86             for(int j = 1; j <= m; j++)
 87             {
 88                 int u = ((i - 1) * m + j) * 2 - 1, v = ((i - 1) * m + j) * 2, w;
 89                 qscanf(w), addedge(++etot, u, v, w);
 90             }
 91         SPFA();
 92     }
 93     else
 94     {
 95         if(m)
 96             n = m;
 97         dis[ttt] = 2147483647;
 98         for(int i = 1; i <= n; i++)
 99         {
100             qscanf(fst[i]);
101             if(dis[ttt] > fst[i])
102                 dis[ttt] = fst[i];
103         }
104     }
105     printf("%d\n", dis[ttt]);
106     return 0;
107 }

时间: 2024-08-02 02:45:20

[BZOJ1001] [Beijing2006] 狼抓兔子 (最短路)的相关文章

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]狼抓兔子

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

BZOJ 1001: [BeiJing2006]狼抓兔子(最短路)

平面图的最小割转化为对偶图的最短路(资料:两极相通——浅析最大最小定理在信息学竞赛中的应用) ,然后DIJKSTRA就OK了. ------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<que

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

【平面图】【最小割】【最短路】【Heap-Dijkstra】bzoj1001 [BeiJing2006]狼抓兔子

http://wenku.baidu.com/view/8f1fde586edb6f1aff001f7d.html #include<cstdio> #include<queue> #include<cstring> using namespace std; typedef long long ll; #define N 1001 int n,m,S,T,nn; struct Point{int u,d;}; bool operator < (Point a,Po

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

浅析最大最小定理在信息学竞赛中的应用---周东 ↑方法介绍 对于一个联通的平面图G(满足欧拉公式) 在s和t间新连一条边e; 然后建立一个原图的对偶图G*,G*中每一个点对应原图中每一个面,每一条边对应分割面的每一条边; 那么对偶图G*中,以原图s和t间边e新划分出的面作为起点(s*),最外的面作为终点(t*); 那么从s*到t*的每一条路都是原图G的一个割; 下图来自上方标出百度文库网址的ppt; 然后用堆(优先队列)优化的迪杰斯特拉,复杂度 O((m+n)logn) n为点数,m为边数...

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

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

bzoj 1001: [BeiJing2006]狼抓兔子 最短路+对偶图

题意:求一个表格图的最小割. 分析:这题如果套上一个网络流的话是会挂的,所以我们要把该图转换成它的对偶图,具体方法可以参照两级相通----浅析最大最小定理在信息学竞赛中的应用 By 周冬.然后跑对短路就好了. 良心的出题人居然没卡spfa 这题要特判n=1 or m=1的情况 这次一开始无限12msWA的原因是spfa的结束条件是until head>=tail,而我用的是循环队列--不想多说,以后一定要注意才行啊. 代码: const maxn=2000009; var s,t,n,m,e:l

BZOJ 1001: [BeiJing2006]狼抓兔子 对偶图

本题是最大流转最小割转对偶图最短路 推荐周东的<浅析最大最小定理在信息学竞赛中的应用> 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MB Submit: 12166  Solved: 2866 [Submit][Status][Discuss] Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在