BZOJ 1001: [BeiJing2006]狼抓兔子
2017-07-14 11:07
260 查看
1001: [BeiJing2006]狼抓兔子
Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 22837 Solved: 5751
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 45 6 4
4 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6
Sample Output
14HINT
2015.4.16新加数据一组,可能会卡掉从前可以过的程序。网络流水水,记得建图的时候都是同时乘以N或者M,看你是横向建点还是纵向建点,大概是在代码中的①处
#include<cstdio> #include<cstring> #include<iostream> #include<queue> using namespace std; const int MAXN=5000000; const int inf=(1<<30)-1; struct Line{ int to,nxt,flow; }line[MAXN*2]; int head[MAXN],tail=1,N,M,level[MAXN]; void add_line(int from,int to,int cost){ tail++; line[tail].to=to; line[tail].nxt=head[from]; line[tail].flow=cost; head[from]=tail; } bool bfs(){ memset(level,-1,sizeof(level)); queue<int>q; q.push(1);level[1]=1; while(!q.empty()){ int u=q.front();q.pop(); // printf("u=%d:\n ",u); for(register int i=head[u];i;i=line[i].nxt){ int v=line[i].to; if(level[v]==-1&&line[i].flow){ level[v]=level[u]+1; q.push(v); // printf("%d ",v); } } // printf("\n"); } return level[N*M]!=-1; } int dfs(int u,int maxflow){ if(u==N*M||maxflow==0) return maxflow; int nowf=0; for(register int i=head[u];i;i=line[i].nxt){ int v=line[i].to; if(line[i].flow&&level[v]==level[u]+1){ int flow=dfs(v,min(maxflow,line[i].flow)); if(flow){ // printf("%d to %d\n",u,v); line[i].flow-=flow; line[i^1].flow+=flow; nowf += flow ; maxflow -= flow; if( !maxflow ) break; } } } if( nowf == 0 ) level[u] = -1 ; return nowf; } int dinic(){ int ans=0; while(bfs()) ans+=dfs(1,inf); return ans; } //第一行为N行,M列.表示网格的大小,N,M均小于等于1000. //第一部分共N行,每行M-1个数,表示横向道路的权值. //第二部分共N-1行,每行M个数,表示纵向道路的权值. //第三部分共N-1行,每行M-1个数,表示斜向道路的权值. int main(){ scanf("%d%d",&N,&M); int cc; for(register int i=1;i<=N;i++){ for(register int j=1;j<=M-1;j++){ scanf("%d",&cc); add_line((i-1)*M+j,(i-1)*M+j+1,cc);//① add_line((i-1)*M+j+1,(i-1)*M+j,cc);//① } } for(register int i=1;i<=N-1;i++){ for(register int j=1;j<=M;j++){ scanf("%d",&cc); add_line((i-1)*M+j,i*M+j,cc);//① add_line(i*M+j,(i-1)*M+j,cc);//① } } for(register int i=1;i<=N-1;i++){ for(register int j=1;j<=M-1;j++){ scanf("%d",&cc); add_line((i-1)*M+j,i*M+j+1,cc);//① add_line(i*M+j+1,(i-1)*M+j,cc);//① } } printf("%d\n",dinic()); return 0; }
相关文章推荐
- BZOJ 1001: [BeiJing2006]狼抓兔子
- bzoj1001: [BeiJing2006]狼抓兔子(网络流模板题:最大流)
- 【bzoj1001】 BeiJing2006—狼抓兔子
- BZOJ1001 [Beijing2006] 狼抓兔子
- 对偶图 && 【BZOJ】1001: [BeiJing2006]狼抓兔子(对偶图+最短路)
- 【BZOJ1001】[BeiJing2006]狼抓兔子
- bzoj 1001: [BeiJing2006]狼抓兔子(s-t平面图求最大流)
- 【bzoj1001】[BeiJing2006]狼抓兔子
- BZOJ 1001([BeiJing2006]狼抓兔子-最大流转对偶图最短路)
- bzoj1001 [BeiJing2006]狼抓兔子
- BZOJ-1001 [BeiJing2006]狼抓兔子
- 【BZOJ】1001: [BeiJing2006]狼抓兔子
- bzoj 1001: [BeiJing2006]狼抓兔子
- BZOJ 1001([BeiJing2006]狼抓兔子-最大流转对偶图最短路)
- [bzoj1001][BeiJing2006]狼抓兔子_网络流_最小割转对偶图
- bzoj 1001: [BeiJing2006]狼抓兔子
- 最小割——BZOJ1001 [BeiJing2006]狼抓兔子
- [bzoj1001][BeiJing2006]狼抓兔子
- [BZOJ1001][BeiJing2006]狼抓兔子 && 平面网络流
- 【BZOJ 1001】[BeiJing2006]狼抓兔子