第一行为N,M.表示网格的大小,N,M均小于等于1000.接下来分三部分第一部分共N行,每行M-1个数,表示横向道路的权值. 第二部分共N-1行,每行M个数,表示纵向道路的权值. 第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 输入文件保证不超过10M
标签:
现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:
左上角点为(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只狼,才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的狼的数量要最小。因为狼还要去找喜羊羊麻烦.
第一行为N,M.表示网格的大小,N,M均小于等于1000.接下来分三部分第一部分共N行,每行M-1个数,表示横向道路的权值. 第二部分共N-1行,每行M个数,表示纵向道路的权值. 第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 输入文件保证不超过10M
输出一个整数,表示参与伏击的狼的最小数量.
958965 | ws_fqk | 1001 | Accepted | 83304 kb | 1924 ms | C++/Edit | 2579 B | 2015-05-01 10:20:13 |
958941 | ws_fqk | 1001 | Time_Limit_Exceed | 83304 kb | 16028 ms | C++/Edit | 2552 B | 2015-05-01 10:07:56 |
958919 | ws_fqk | 1001 | Time_Limit_Exceed | 87208 kb | 16032 ms | C++/Edit | 2522 B | 2015-05-01 09:48:54 |
先让我哭一会……坑了我好久的题。
开始时dinic怎么写都超时,于是看了题解,是一个奇怪的最短路……让我很不解。后来同校的大神用dinic过了……于是乎,我就改了一上午的dinic,终于过掉了。
分析:
建图没什么好说的,直接挨着标号,处理好坐标就好了。然后就是dinic。
很久以来,我写dinic一直是N次dfs找增广路直到找不到。然后就出现了16000+MS完美Time_Limit_Exceed……超时不可能出现在BFS距离标号上,那就只能是增广路的问题了。
做了一点小改动……直接秒了。详见代码。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<vector> #include<cmath> using namespace std; int next[6000000],head[1000001],list[6000000],key[6000000],dis[1000001],q[1000001],n,m,top,ans,sum,delta,x; void insert(int x,int y,int z) { top++; next[top]=head[x]; head[x]=top; list[top]=y; key[top]=z; } bool BFS() { memset(dis,0xff,sizeof(dis)); dis[1]=0; int x,y,l=0,r=1; q[1]=1; while (l<r) { l++; y=q[l]; x=head[y]; while (x!=0) { if (dis[list[x]]<0&&key[x]>0) { dis[list[x]]=dis[y]+1; r++; q[r]=list[x]; } x=next[x]; } } if (dis[sum]>0) return true; else return false; } int find(int x,int flow) { if (x==sum) return flow; int a=0,y=head[x],ff=0; while (y!=0) { if (key[y]>0&&dis[list[y]]==dis[x]+1) { a=flow-ff; a=find(list[y],min(key[y],a)); key[y]-=a; key[y^1]+=a; ff+=a; if (ff==flow) return flow; } y=next[y]; } if (!ff) dis[x]=-1; 关键就在这一句啊! return ff; } int main() { scanf("%d%d",&n,&m); top=0; for (int i=1;i<=n;i++) for (int j=1;j<m;j++) { scanf("%d",&x); insert((i-1)*m+j,(i-1)*m+j+1,x); insert((i-1)*m+j+1,(i-1)*m+j,x); } for (int i=1;i<n;i++) for (int j=1;j<=m;j++) { scanf("%d",&x); insert((i-1)*m+j,i*m+j,x); insert(i*m+j,(i-1)*m+j,x); } for (int i=1;i<n;i++) for (int j=1;j<m;j++) { scanf("%d",&x); insert((i-1)*m+j,i*m+j+1,x); insert(i*m+j+1,(i-1)*m+j,x); } ans=0; sum=n*m; while (BFS()) ans+=find(1,0x7fffffff); printf("%d",ans); return 0; }
标签:
原文地址:http://www.cnblogs.com/ws-fqk/p/4470441.html