【BZOJ1001】狼抓兔子(网络流)
【BZOJ1001】狼抓兔子(网络流)
题面
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
题解
网络流模板题呀。。。
没了
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> using namespace std; #define MAXL 3000*3000 #define MAX 3000*1000 #define INF 1000000000 #define rg register inline int read() { rg int x=0,t=1;rg char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return x*t; } struct Line { int v,next,w; }e[MAXL]; int h[MAX],cnt; int ans,S,T,n,m; inline void Add(int u,int v,int w) { e[cnt]=(Line){v,h[u],w}; h[u]=cnt++; e[cnt]=(Line){u,h[v],w}; h[v]=cnt++; } int level[MAX]; int cur[MAX]; bool BFS() { memset(level,0,sizeof(level)); level[S]=1; queue<int> Q; Q.push(S); while(!Q.empty()) { int u=Q.front();Q.pop(); for(int i=h[u];i!=-1;i=e[i].next) { int v=e[i].v; if(e[i].w&&!level[v]) level[v]=level[u]+1,Q.push(v); } } return level[T]; } int DFS(int u,int flow) { if(flow==0||u==T)return flow; rg int ret=0; for(int i=h[u];i!=-1;i=e[i].next) { rg int v=e[i].v; if(e[i].w&&level[v]==level[u]+1) { rg int dd=DFS(v,min(flow,e[i].w)); flow-=dd;ret+=dd; e[i].w-=dd;e[i^1].w+=dd; } } if(!ret)level[u]=0; return ret; } int Dinic() { rg int ret=0; while(BFS()) { //for(int i=S;i<=T;++i)cur[i]=h[i]; ret+=DFS(S,INF); } return ret; } int main() { memset(h,-1,sizeof(h)); n=read();m=read(); S=0;T=n*m+1; Add(S,1,INF); for(rg int i=0;i<n;++i) for(rg int j=1;j<m;++j) { rg int w=read(); Add(i*m+j,i*m+j+1,w); } for(rg int i=0;i<n-1;++i) for(rg int j=1;j<=m;++j) { rg int w=read(); Add(i*m+j,i*m+j+m,w); } for(rg int i=0;i<n-1;++i) for(rg int j=1;j<m;++j) { rg int w=read(); Add(i*m+j,i*m+j+m+1,w); } Add(n*m,T,INF); printf("%d\n",Dinic()); return 0; }