【BZOJ 1001】[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
 
话说暴力出奇迹
他们都说这个题是最小割,转对偶图之后跑最短路
然而我并不会写对偶图,所以就网上扔了一个最大流,结果A了。。。
如图建边,dinic一定要写的足够快,否则会T,比如像我
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 using namespace std;
 6 const int inf=100000000,N=1010000;
 7 struct ee{int to,next,f;}e[12000010];
 8 int head[N],q[N*2],dis[N];
 9 int S,T,n,m,cnt=1,ans,w;
10  
11 void ins(int u,int v,int f){
12     e[++cnt].to=v;e[cnt].f=f;e[cnt].next=head[u];head[u]=cnt;
13     e[++cnt].to=u;e[cnt].f=0;e[cnt].next=head[v];head[v]=cnt;
14 }
15  
16 bool bfs(){
17     for (int i=1;i<=T;i++) dis[i]=inf;
18     int h=0,t=1,now;
19     q[1]=S;dis[S]=0;
20     while(h!=t){
21         now=q[++h];
22         for (int i=head[now];i;i=e[i].next){
23             int v=e[i].to;
24             if (e[i].f&&dis[now]+1<dis[v]){
25                 dis[v]=dis[now]+1;
26                 if (v==T)return 1;
27                 q[++t]=v;
28             }
29         }
30     }
31     if (dis[T]==inf) return 0; return 1;
32 }
33  
34 int dinic(int now,int f){
35     if (now==T) return f;
36     int rest=f;
37     for (int i=head[now];i;i=e[i].next){
38         int v=e[i].to;
39         if (e[i].f&&dis[v]==dis[now]+1&&rest){
40             int t=dinic(v,min(rest,e[i].f));
41             if (!t) dis[v]=0;
42             e[i].f-=t;
43             e[i^1].f+=t;
44             rest-=t;
45             //if(t) printf("%d %d %d\n",now,v,e[i].f);
46         }
47     }
48     return f-rest;
49 }
50 int  main(){
51     scanf("%d%d",&n,&m);
52     S=0,T=n*m+1;
53     ins(S,1,inf);ins(n*m,T,inf);
54     for (int i=1;i<=n;i++)
55         for (int j=1;j<=m-1;j++){
56             scanf("%d",&w);
57             int u=(i-1)*m+j;
58             ins(u,u+1,w);
59             ins(u+1,u,w);
60         }
61     for (int i=1;i<=n-1;i++)
62         for (int j=1;j<=m;j++){
63             scanf("%d",&w);
64             int u=(i-1)*m+j;
65             ins(u,u+m,w);
66             ins(u+m,u,w);
67         }
68     for (int i=1;i<=n-1;i++)
69         for(int j=1;j<=m-1;j++){
70             scanf("%d",&w);
71             int u=(i-1)*m+j;
72             ins(u,u+m+1,w);
73             ins(u+m+1,u,w);
74         }
75     while (bfs()) 
76     ans+=dinic(S,inf); 
77     printf("%d",ans);
78     return 0;
79 } 
80 

 

posted @ 2016-02-13 21:28  Alisahhh  阅读(216)  评论(0编辑  收藏  举报