时间来不及了,先贴代码吧!有时间再写。

好苦逼啊,WA了若干次,还有一次RE,一次TLE。

虽然主要运用的算法和资料都由师兄提供了。还是太弱了,太天真了。

首先,数据范围就WA了,RE了,TLE了。

然后构图上有bug。最后还是仿着师兄的把构图重新写了。加油吧!

这道题的主要思路首先应该是网络流中的最小割,但由于数据范围太大,直接用最小割的算法会TLE,而且没有正确地利用题目特征,这道题的图是个S-T图,我们可以建出原图的对偶图,然后跑一次dijkstra()。详情请参考《浅析最大最小定理在信息学竞赛中的应用》。

一个网格图中求最小割,很特殊的是这个图是一个平面图,最小割=最大流=对偶图中最短路(平面图)。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<queue>
  4 #include<cstring>
  5 #define maxn 2100009
  6 #define rep(i,j,k) for(int i = j; i <= k; i++)
  7 using namespace std;
  8
  9 int read()
 10 {
 11     int s = 0, t = 1; char c = getchar();
 12     while( !isdigit(c) ) {
 13         if( c == '-' ) t = -1; c = getchar();
 14     }
 15     while( isdigit(c) ){
 16         s = s * 10 + c - '0'; c = getchar();
 17     }
 18     return s * t;
 19 }
 20
 21 int d[maxn], n, m, sx, tx;
 22 bool done[maxn] = {0};
 23
 24 struct node{
 25 int d, u;
 26 bool operator < (const node& rhs) const{
 27         return d > rhs.d;
 28      }
 29 };
 30
 31 struct edge{
 32 int to, key;
 33 edge* next;
 34 };
 35
 36 edge *pt, edges[maxn*3], *head[maxn];
 37
 38 void add_edge(int x,int y,int val){
 39    pt->to = y;pt->key = val;
 40    pt->next = head[x];
 41    head[x] = pt++;
 42    pt->to = x, pt->key= val;
 43    pt->next = head[y];
 44    head[y] = pt++;
 45 }
 46 priority_queue<node> Q;
 47
 48 void dijkstra()
 49 {
 50      memset(d,127,sizeof(d));
 51      d[sx] = 0;
 52      Q.push((node){0,sx});
 53      while( !Q.empty() ){
 54         node x = Q.top(); Q.pop();
 55         int u = x.u;
 56         if( done[u] ) continue;
 57         done[u] = 1;
 58         for( edge*i = head[u]; i ; i = i->next ){
 59             int y = i->to, key = i->key;
 60             if( d[y] > d[u]+key ) {
 61                 d[y] = d[u]+key;
 62                 Q.push((node){d[y],y});
 63             }
 64         }
 65      }
 66 }
 67
 68 int main()
 69 {
 70     //freopen("out.txt","w",stdout);
 71    pt = edges;
 72    n = read(), m = read();
 73    sx = 0, tx = (n-1)*(m-1) * 2+ 1;
 74    rep(i,0,n-1) {
 75       int xx = (2*m-2)*i;
 76       int xy = (2*m-2)*(i-1);
 77       rep(j,1,m-1){
 78          int x = read();
 79          if( !i ) {
 80             add_edge(xx+2*j,tx,x);
 81             //cout<<tx<<" "<<xx+2*j+1<<" "<<x<<endl;
 82          }
 83          else if( i == n-1 ) {
 84             add_edge(sx,xy+2*j-1,x);
 85             //cout<<xy+2*j<<" "<<sx<<" "<<x<<endl;
 86          }
 87          else{
 88             add_edge(xx+2*j,xy+2*j-1,x);
 89             //cout<<xy+2*j<<" "<<xx+2*j+1<<" "<<x<<endl;
 90          }
 91       }
 92    }
 93    rep(i,0,n-2){
 94       int xx = 2*(m-1)*(i);
 95       rep(j,1,m){
 96          int x = read();
 97          if( j == 1 ){
 98             add_edge(sx,xx+2*j-1,x);
 99             //cout<<sx<<" "<<xx<<" "<<x<<endl;
100          }
101          else if( j == m ){
102             add_edge(tx,xx+2*j-2,x);
103             //cout<<tx<<" "<<xx+2*j-1<<" "<<x<<endl;
104          }
105          else {
106             add_edge(xx+2*j-2,xx+2*j-1,x);
107             //cout<<xx+2*j<<" "<<xx+2*j-1<<" "<<x<<endl;
108          }
109       }
110    }
111    rep(i,0,n-2){
112      int xx = 2*(m-1)*(i);
113      rep(j,1,m-1){
114         int x = read();
115         add_edge(xx+2*j,xx+2*j-1,x);
116         //cout<<xx+2*j<<" "<<xx+2*j+1<<" "<<endl;
117      }
118    }
119    dijkstra();
120    cout<<d[tx]<<endl;
121    return 0;
122 }

不过,也想请大神把我指出下面这份代码错哪了?

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<queue>
  4 #include<cstring>
  5 #define maxn 2100009
  6 #define sx   2100000
  7 #define tx   2100001
  8 #define rep(i,j,k) for(int i = j; i <= k; i++)
  9 using namespace std;
 10
 11 int read()
 12 {
 13     int s = 0, t = 1; char c = getchar();
 14     while( !isdigit(c) ) {
 15         if( c == '-' ) t = -1; c = getchar();
 16     }
 17     while( isdigit(c) ){
 18         s = s * 10 + c - '0'; c = getchar();
 19     }
 20     return s * t;
 21 }
 22
 23 int d[maxn], n, m;
 24 bool done[maxn] = {0};
 25
 26 struct node{
 27 int d, u;
 28 bool operator < (const node& rhs) const{
 29         return d > rhs.d;
 30      }
 31 };
 32
 33 struct edge{
 34 int to, key;
 35 edge* next;
 36 };
 37
 38 edge *pt, edges[maxn*3], *head[maxn];
 39
 40 void add_edge(int x,int y,int val){
 41    pt->to = y;pt->key = val;
 42    pt->next = head[x];
 43    head[x] = pt++;
 44    pt->to = x, pt->key= val;
 45    pt->next = head[y];
 46    head[y] = pt++;
 47 }
 48 priority_queue<node> Q;
 49
 50 void dijkstra()
 51 {
 52      memset(d,127,sizeof(d));
 53      d[sx] = 0;
 54      Q.push((node){0,sx});
 55      while( !Q.empty() ){
 56         node x = Q.top(); Q.pop();
 57         int u = x.u;
 58         if( done[u] ) continue;
 59         done[u] = 1;
 60         for( edge*i = head[u]; i ; i = i->next ){
 61             int y = i->to, key = i->key;
 62             if( d[y] > d[u]+key ) {
 63                 d[y] = d[u]+key;
 64                 Q.push((node){d[y],y});
 65             }
 66         }
 67      }
 68 }
 69
 70 int main()
 71 {
 72     //freopen("out.txt","w",stdout);
 73    pt = edges;
 74    n = read(), m = read();
 75    rep(i,0,n-1) {
 76       int xx = (2*m-2)*i;
 77       int xy = (2*m-2)*(i-1);
 78       rep(j,0,m-2){
 79          int x = read();
 80          if( !i ) {
 81             add_edge(xx+2*j+1,tx,x);
 82             //cout<<tx<<" "<<xx+2*j+1<<" "<<x<<endl;
 83          }
 84          else if( i == n-1 ) {
 85             add_edge(sx,xy+2*j,x);
 86             //cout<<xy+2*j<<" "<<sx<<" "<<x<<endl;
 87          }
 88          else{
 89             add_edge(xx+2*j+1,xy+2*j,x);
 90             //cout<<xy+2*j<<" "<<xx+2*j+1<<" "<<x<<endl;
 91          }
 92       }
 93    }
 94    rep(i,0,n-2){
 95       int xx = 2*(m-1)*(i);
 96       rep(j,0,m-1){
 97          int x = read();
 98          if( !j ){
 99             add_edge(sx,xx,x);
100             //cout<<sx<<" "<<xx<<" "<<x<<endl;
101          }
102          else if( j == m-1 ){
103             add_edge(tx,xx+2*j-1,x);
104             //cout<<tx<<" "<<xx+2*j-1<<" "<<x<<endl;
105          }
106          else {
107             add_edge(xx+2*j,xx+2*j-1,x);
108             //cout<<xx+2*j<<" "<<xx+2*j-1<<" "<<x<<endl;
109          }
110       }
111    }
112    rep(i,0,n-2){
113      int xx = 2*(m-1)*(i);
114      rep(j,0,m-2){
115         int x = read();
116         add_edge(xx+2*j,xx+2*j+1,x);
117         //cout<<xx+2*j<<" "<<xx+2*j+1<<" "<<endl;
118      }
119    }
120    dijkstra();
121    cout<<d[tx]<<endl;
122    return 0;
123 }

1001: [BeiJing2006]狼抓兔子

Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 14595  Solved: 3490
[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

转载于:https://www.cnblogs.com/83131yyl/p/5046130.html

BZOJ1001 狼抓兔子 终于过了!相关推荐

  1. [bzoj1001]狼抓兔子

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

  2. bzoj1001狼抓兔子

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

  3. 【BJOI2006】bzoj1001 狼抓兔子

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

  4. BZOJ1001 狼抓兔子

    最小割 代码 # include <bits/stdc++.h> # define IL inline # define RG register # define Fill(a, b) m ...

  5. 【BZOJ1001】狼抓兔子

    [BZOJ1001]狼抓兔子 题面 bzoj 题解 懒得平面图转对偶图了,直接最小割板子加优化. #include <iostream> #include <cstdio> # ...

  6. 【BZOJ1001】狼抓兔子题解

    BZOJ1001: [BeiJing2006]狼抓兔子 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还 ...

  7. 【bzoj1001】【狼抓兔子】

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MB Submit: 12719 Solved: 3017 [Submit][ ...

  8. bzoj1001/BJOI2006 狼抓兔子

    1001: [BeiJing2006]狼抓兔子(传送门) 图论新知识..没学过.. 平面图最小割等于对偶图的最短路 详见课件:http://wenku.baidu.com/view/8f1fde586 ...

  9. 狼抓兔子(平面图转对偶图)

    狼抓兔子(平面图转对偶图) 面对下面这样一个网格的地形: 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(1,1)的窝里,现 ...

最新文章

  1. C语言连续指针_只愿与一人十指紧扣_新浪博客
  2. Flash 组件定义(AS3)
  3. 索引的优点,索引优化原则
  4. ssm项目之maven添加pom jar包配置
  5. 聊一聊声明式接口调用与Nacos的结合使用
  6. 【Leetcode | 47】 222. 完全二叉树的节点个数
  7. python 循环指定次数_亮仔的Python之路Day7——Python循环语句
  8. 基于深度卷积神经网络的农作物病害识别
  9. 启动tomcat和java步骤
  10. MySQL连接问题 --- (1251:Client does not support ...)
  11. php header带session,PHP接口跨域header头以及Session跨域方法
  12. 第五章平稳过程(1)
  13. php支付宝刷脸api,支付宝人脸识别
  14. 今日头条是怎么盈利的?
  15. mysql cmd全屏_CSS全屏布局的5种方式
  16. Python NLP 入门教程
  17. 互联网日报 | 6月11日 星期五 | 滴滴正式提交赴美IPO申请;百度再投20亿成立造车公司;盒马集市将推出“盒字号”商品...
  18. 若非群玉山头见,会向瑶台月下逢
  19. 计算机毕业设计asp.net的高校科研项目管理系统(源码+系统+mysql数据库+Lw文档)
  20. STM32MP157驱动开发——Linux RS232/485/GPS 驱动

热门文章

  1. 计算机系统组装 维护常用工具及其作用,《计算机系统组装维护》课程实用标准.doc...
  2. 办公效率:从事会计行业,这些Excel技巧绝对用得着!
  3. 分布式数据库技术基础:分布透明性相关知识
  4. 计算机系统基础:文件管理相关知识笔记
  5. 前端:Web技术的演化史
  6. 高并发场景下的缓存有哪些常见的问题?
  7. matlab找不到函数系统函数,求助,Matlab找不到ztrans函数
  8. 计算机电子琴弹奏怎么打开,怎么打开电脑键盘电子琴软件
  9. mysql数据库算法_数据库:MySQL索引背后的数据结构及算法原理【转】
  10. Could not autowire. No beans of 'JavaMailSender' type found..md