bzoj1001 狼抓兔子
这道题 我只会最大流写法 加了当前弧优化就过了 只看代码就oaky了 相信各位大佬都懂的 不过这道题反向弧和反向边可以弄在一起 会快很多
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=1000005,inf=0x3f3f3f3f; 6 int n,m,sum=1,S,T; 7 long long ans; 8 int read(){ 9 int ans=0,f=1,c=getchar(); 10 while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();} 11 while(c>='0'&&c<='9') {ans=ans*10+(c-'0'); c=getchar();} 12 return ans*f; 13 } 14 int first[maxn],d[maxn],q[maxn],cur[maxn]; 15 struct node{int flow,to,next;}e[6*maxn]; 16 void add(int a,int b,int w){ 17 sum++; e[sum].to=b; e[sum].flow=w; e[sum].next=first[a]; first[a]=sum; 18 sum++; e[sum].to=a; e[sum].flow=w; e[sum].next=first[b]; first[b]=sum; 19 } 20 int bfs(){ 21 memset(d,-1,sizeof(d)); 22 int head=0,tail=1; q[0]=S; d[S]=0; 23 while(head!=tail){ 24 int x=q[head++]; if(head>=maxn) head=0; 25 for(int i=first[x];i;i=e[i].next){ 26 int now=e[i].to; 27 if(d[now]==-1&&e[i].flow){d[now]=d[x]+1; q[tail++]=now; if(tail>=maxn) tail=maxn;} 28 } 29 } 30 if(d[T]==-1) return 0; 31 return 1; 32 } 33 int dfs(int x,int a){ 34 if(x==T||a==0) return a; 35 int f,flow=0; 36 for(int &i=cur[x];i;i=e[i].next){ 37 int now=e[i].to; 38 if(d[now]==d[x]+1&&(f=dfs(now,min(a,e[i].flow)))>0){ 39 e[i].flow-=f; 40 e[i^1].flow+=f; 41 flow+=f; 42 a-=f; 43 if(!a) break; 44 } 45 } 46 return flow; 47 } 48 int main() 49 { 50 int x; 51 n=read(); m=read(); 52 S=1; T=n*m; 53 for(int i=1;i<=n;i++) 54 for(int j=1;j<m;j++) {x=read();int v=(i-1)*m+j; add(v,v+1,x);} 55 for(int i=1;i<n;i++) 56 for(int j=1;j<=m;j++) {x=read(); int v=(i-1)*m+j; add(v,v+m,x);} 57 for(int i=1;i<n;i++) 58 for(int j=1;j<m;j++) {x=read(); int v=(i-1)*m+j; add(v,v+m+1,x);} 59 while(bfs()){ for(int i=1;i<=n*m;i++) cur[i]=first[i]; ans=ans+dfs(S,inf);} 60 printf("%lld\n",ans); 61 return 0; 62 }