bzoj 1001 狼抓兔子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1001 狼抓兔子相关的知识,希望对你有一定的参考价值。
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
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新加数据一组,可能会卡掉从前可以过的程序。
平面图求最小割,所以可以用spfa做。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 const int N = 1000 + 7, M = 2000000 + 7, inf = 1 << 30; 6 using namespace std; 7 int n,m,s,t,cnt,head[M],dis[M]; 8 bool used[M]; 9 struct edges 10 { 11 int nxt,to,wi; 12 } E[M * 3]; 13 14 int idid(int a,int b) 15 { 16 return (a - 1) * (m - 1) * 2 + b * 2; 17 } 18 19 void add(int u,int v,int wi) 20 { 21 E[++cnt] = (edges){head[u],v,wi};head[u] = cnt; 22 E[++cnt] = (edges) {head[v],u,wi}; head[v] = cnt; 23 } 24 25 void Init() 26 { 27 scanf("%d%d",&n,&m); 28 if(n == 1 || m == 1) 29 { 30 if(n == 1) swap(n,m); 31 int ans = inf, c; 32 for(int i = 1; i < n; ++i) 33 { 34 scanf("%d",&c); 35 ans = min(ans,c); 36 } 37 printf("%d\n",ans); return; 38 } 39 int c;s = 0, t = ((n-1) * (m-1) << 1) + 1; 40 for(int i = 1; i <= n; ++i) 41 for(int j = 1; j < m; ++j) 42 { 43 scanf("%d",&c); 44 if(i == 1) add(s,j<<1,c); 45 else if(i == n) add(idid(i-1,j)-1,t,c); 46 else add(idid(i-1,j)-1,idid(i,j),c); 47 } 48 49 for(int i = 1; i < n; ++i) 50 for(int j = 1; j <= m; ++j) 51 { 52 scanf("%d",&c); 53 if(j == 1) add(idid(i,j)-1,t,c); 54 else if(j == m) add(s,idid(i,j-1),c); 55 else add(idid(i,j-1),idid(i,j)-1,c); 56 } 57 for(int i = 1;i < n; ++i) 58 for(int j = 1 ; j < m; ++j) 59 { 60 scanf("%d",&c); 61 add(idid(i,j)-1,idid(i,j),c); 62 } 63 } 64 65 void dij() 66 { 67 queue<int> Q; 68 memset(dis,127/2,sizeof(dis)); 69 memset(used,false,sizeof(used)); used[s] = true; 70 Q.push(s); dis[s] = 0; 71 while(!Q.empty()) 72 { 73 int u = Q.front(); Q.pop(); used[u] = false; 74 for(int i = head[u]; i; i = E[i].nxt) 75 { 76 int v = E[i].to; 77 if(dis[v] <= dis[u] + E[i].wi) continue; 78 dis[v] = dis[u] + E[i].wi; 79 if(used[v]) continue; 80 Q.push(v); used[v] = true; 81 } 82 } 83 } 84 85 void Solve() 86 { 87 dij(); 88 printf("%d\n",dis[t]); 89 } 90 91 int main() 92 { 93 // freopen("1.in","r",stdin); 94 Init(); 95 if(n == 1 || m == 1) return 0; 96 Solve(); 97 return 0; 98 } 99
以上是关于bzoj 1001 狼抓兔子的主要内容,如果未能解决你的问题,请参考以下文章