bzoj1001: [BeiJing2006]狼抓兔子 -- 最小割
1001: [BeiJing2006]狼抓兔子
Time Limit: 15 Sec Memory Limit: 162 MBDescription
现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,
而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:
左上角点为(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新加数据一组,可能会卡掉从前可以过的程序。
Source
最大流最小割定理
#include<queue> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define F(i,l,r) for(int i=l;i<r;i++) #define N 1000001 #define inf 1e9+5 inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct ljn{int fro,to,v;}e[N*6]; int cnt=1,lj[N],n,m,tt,ans=0,S,T,dis[N]; inline void add(int u,int v,int p){cnt++;e[cnt].to=v;e[cnt].fro=lj[u];e[cnt].v=p;lj[u]=cnt;} inline bool bfs() { F(i,S,T+1) dis[i]=0; dis[S]=1; static queue<int>q; q.push(S); while(!q.empty()) { int tp=q.front(); q.pop(); for(int i=lj[tp];i;i=e[i].fro) { if(e[i].v&&!dis[e[i].to]) { dis[e[i].to]=dis[tp]+1; q.push(e[i].to); } } } return dis[T]?1:0; } inline int dfs(int x,int p) { if(x==T||p==0) return p; int tmp=0,tp; for(int i=lj[x];i;i=e[i].fro) { if(e[i].v&&dis[e[i].to]==dis[x]+1) { tp=dfs(e[i].to,min(p-tmp,e[i].v)); e[i].v-=tp; e[i^1].v+=tp; tmp+=tp; if(p==tmp) return tmp; } } if(tmp==0) dis[x]=0; return tmp; } int main() { n=read();m=read(); S=0;T=n*m+1; add(S,1,inf);add(1,S,inf); add(m*n,T,inf);add(T,m*n,inf); F(i,0,n) F(j,1,m) { tt=read(); add(i*m+j,i*m+j+1,tt); add(i*m+j+1,i*m+j,tt); } F(i,0,n-1) F(j,1,m+1) { tt=read(); add(i*m+j,(i+1)*m+j,tt); add((i+1)*m+j,i*m+j,tt); } F(i,0,n-1) F(j,1,m) { tt=read(); add(i*m+j,(i+1)*m+j+1,tt); add((i+1)*m+j+1,i*m+j,tt); } while(bfs()) ans+=dfs(S,inf); printf("%d\n",ans); }
版权声明:本文为博主原创文章,未经博主允许不得转载。