[BZOJ 1001] [BeiJing2006]狼抓兔子

1001: [BeiJing2006]狼抓兔子

Time Limit: 15 Sec
Memory Limit: 162 MB

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

Source

【题解&吐槽】

Q:最近怎么人不见了?

A:去玩了

Q:去哪里玩了?

A:欧洲啊

WOW~~~

于是回来后开始苦逼的填天坑了。

从这题开始吧

很早很早之前,NoiAu的ysy就给我讲过这题

然而我一直没去写,平面图网络流可以转化成最短路来做,把闭合面看成点,相邻面的边就是这两点的连线,然后dijkstra+heap跑最短路就行了。

  1 #include <stdio.h>
  2 #include <queue>
  3 #include <string.h>
  4 
  5 using namespace std;
  6 
  7 struct edge {
  8     int to,w,next;
  9 }e[6000100];
 10 struct node {
 11     int now, dist;
 12     node() { }
 13     node(int _now,int _dist) {
 14         now=_now;
 15         dist=_dist;
 16     }
 17     bool operator <(const node x) const {
 18         return dist > x.dist;
 19     }
 20 };
 21 
 22 int n, m, num, sum, head[2000100], d[2000100];
 23 bool flag[2000100];
 24 
 25 inline void add(int _x,int _y,int _w) {
 26     e[++num].to=_y;
 27     e[num].w=_w;
 28     e[num].next=head[_x];
 29     head[_x]=num;
 30 }
 31 
 32 inline void getint(int &_x) {
 33     int x=0,f=1;char ch=getchar();
 34     while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();}
 35     while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
 36     _x=x*f;
 37 } 
 38 
 39 int main() {
 40     getint(n), getint(m);
 41     if (n==1 || m==1) {
 42         if(n>m) swap(n,m);
 43         int ans=2100000000;
 44         for (int i=1,_xy;i<m;++i) {
 45             getint(_xy);
 46             if(_xy<ans) ans=_xy;
 47         }
 48         printf("%d
",ans);
 49         return 0;
 50     }
 51     int l=n-1,r=m-1;
 52     sum=2*l*r;
 53     for (int i=1,_xy;i<=n;++i) {
 54         for (int j=1,_t;j<m;++j) {
 55             getint(_xy);
 56             _t=(i-1)*r+j;
 57             int x,y;
 58             y=_t<<1;
 59             x=y-2*r-1;
 60             if(i==1) x=0;
 61             else if(i==n) y=sum+1;
 62             add(x,y,_xy);
 63             add(y,x,_xy);
 64         }
 65     }
 66     for (int i=1,_xy;i<n;++i) {
 67         for (int j=1,_t;j<=m;++j) {
 68             getint(_xy);
 69             _t=(i-1)*r+j-1;
 70             int x,y;
 71             x=_t<<1;
 72             y=x|1;
 73             if(j==1) x=sum+1;
 74             else if(j==m) y=0;
 75             add(x,y,_xy);
 76             add(y,x,_xy);
 77         }
 78     }
 79     for (int i=1,_xy;i<n;++i) {
 80         for (int j=1,_t;j<m;++j) {
 81             getint(_xy);
 82             _t=(i-1)*r+j;
 83             int x,y;
 84             y=_t<<1;
 85             x=y-1;
 86             add(x,y,_xy);
 87             add(y,x,_xy);
 88         }
 89     }
 90     priority_queue<node> q;
 91     for (int i=1;i<=sum+1;++i) d[i]=210000000;
 92     q.push(node(0,0));
 93     while(!q.empty()) {
 94         int x=q.top().now;
 95         q.pop();
 96         if(flag[x]) continue;
 97         for (int i=head[x];i;i=e[i].next) {
 98             int to=e[i].to;
 99             if(d[to]>d[x]+e[i].w) {
100                 d[to]=e[i].w+d[x];
101                 q.push(node(to,d[to]));
102             }
103         }
104     }
105     printf("%d
",d[sum+1]);
106     return 0;
107 }
View Code

恭喜Noi2015,ysy顺利Au屠场!

原文地址:https://www.cnblogs.com/TonyNeal/p/bzoj1001.html