bzoj1001(网络流,最小割)狼抓兔子

来源:互联网 发布:行知职校 编辑:程序博客网 时间:2024/06/05 09:53

第一个博客,刷道水题吧。。。最大流=最小割

#include<cstdio>#include<cctype>#include<cstring>#include<vector>#include<algorithm>#include<iostream>using namespace std;const int N=1000005,M=6000005;const int oo=2e9+7;int a[N],b[N],nedge,son[N],tot,n,m,gap[N],d[N],que[N],l,r;struct edge{int nextt,ed,di;}e[M];inline intread()//²»¹ÜÊÇÕý¸ºÊý£¬¶¼¿ÉÒÔ {int x = 0; char ch = getchar(); bool positive = 1;for (; !isdigit(ch); ch = getchar())if (ch == '-')positive = 0;for (; isdigit(ch); ch = getchar())x = x * 10 + ch - '0';return positive ? x : -x;}inline void write(int a){if(a>=10)write(a/10);putchar('0'+a%10);}inline void writeln(int a){write(a); puts("");}inline void aedge(int a,int b,int c){e[++nedge].nextt=son[a];son[a]=nedge;e[nedge].ed=b;e[nedge].di=c;}inline void ycl(int s,int t) {    memset(gap,0,sizeof gap),memset(d,0,sizeof d),++gap[d[t]=1];    que[l=r=1]=t;    while(l<=r){        int k=que[l++];        for (int i=son[k];i;i=e[i].nextt)if(!d[e[i].ed])++gap[d[e[i].ed]=d[k]+1],que[++r]=e[i].ed;    }}inline int aug(int x,int s,int t,int mmin) {    if(x==t)return mmin;    int flow=0;    for(int i=son[x];i;i=e[i].nextt)if(d[x]==d[e[i].ed]+1){        int tmp=aug(e[i].ed,s,t,min(mmin,e[i].di));        flow+=tmp;mmin-=tmp;e[i].di-=tmp;e[((i-1)^1)+1].di+=tmp;        if(!mmin)return flow;    }    if(!(--gap[d[x]]))d[s]=n+1; ++gap[++d[x]];    return flow;}inline int maxflow(int s,int t) {    ycl(s,t); int ans=aug(s,s,t,oo);    while(d[s]<=n)ans+=aug(s,s,t,oo);    return ans;}int main(){    int nn=read(),mm=read(); n=nn*mm;    for(int i=1;i<=nn;i++)for(int j=1;j<mm;j++){    int s1=read(); aedge((i-1)*mm+j,(i-1)*mm+j+1,s1); aedge((i-1)*mm+j+1,(i-1)*mm+j,s1);}for(int i=1;i<nn;i++)for(int j=1;j<=mm;j++){int s1=read(); aedge((i-1)*mm+j,i*mm+j,s1); aedge(i*mm+j,(i-1)*mm+j,s1);}for(int i=1;i<nn;i++)for(int j=1;j<mm;j++){int s1=read(); aedge((i-1)*mm+j,i*mm+j+1,s1); aedge(i*mm+j+1,(i-1)*mm+j,s1);}cout<<maxflow(1,n)<<endl;}

阅读全文
0 0