[BZOJ]1001: [BeiJing2006]狼抓兔子

来源:互联网 发布:mac app store更新不了 编辑:程序博客网 时间:2024/06/06 06:41
一道网络流的裸题,但是要注意双向边的建法,我因为太久没打过网络流,建多了很多重复的边,导致TLE。。。。。。
/**************************************************************    Problem: 1001    User: 200815147    Language: C++    Result: Accepted    Time:2060 ms    Memory:106292 kb****************************************************************/ #include<cstdio>#include<cstring>const int Q=1000005;const int MAX=999999999;int n,m,st,ed;int p(int x,int y) {return (x-1)*m+y;}struct edge{    int y,d,next,other;}a[6*Q];int len=0,last[Q];void ins(int x,int y,int d){    int t1=++len;    a[t1].y=y;a[t1].d=d;a[t1].next=last[x];last[x]=t1;    int t2=++len;    a[t2].y=x;a[t2].d=d;a[t2].next=last[y];last[y]=t2;    a[t1].other=t2;a[t2].other=t1;}int h[Q],list[Q];bool build(){    memset(h,0,sizeof(h));h[st]=1;    list[1]=st;    int head=1,tail=2;    while(head!=tail)    {        int x=list[head];        for(int i=last[x];i!=-1;i=a[i].next)        {            int y=a[i].y;            if(a[i].d>0 && h[y]==0)            {                h[y]=h[x]+1;                list[tail++]=y;                if(tail==Q-1) tail=1;            }        }        head++;        if(head==Q-1) head=1;    }    if(h[ed]>0) return true;    return false;}int mymin(int x,int y) {return x<y?x:y;}int work(int x,int f){    if(x==ed) return f;    int s=0;    for(int i=last[x];i!=-1;i=a[i].next)    {        int y=a[i].y;        if(a[i].d>0 && h[y]==h[x]+1 && s<f)        {            int t=work(y,mymin(f-s,a[i].d));            s+=t;a[a[i].other].d+=t;a[i].d-=t;        }    }    if(s==0) h[x]=0;    return s;}int main(){    memset(last,-1,sizeof(last));    scanf("%d%d",&n,&m);    if(n==1&&m==1) {printf("0");return 0;}    for(int i=1;i<=n;i++)    {        for(int j=1;j<m;j++)        {            int d,num1=(i-1)*m+j;            scanf("%d",&d);            ins(num1,num1+1,d);            //ins(num1+1,num1,d);        }    }    for(int i=1;i<n;i++)    {        for(int j=1;j<=m;j++)        {            int d,num1=(i-1)*m+j,num2=num1+m;            scanf("%d",&d);            ins(num2,num1,d);            //ins(num1,num2,d);        }    }    for(int i=1;i<n;i++)    {        for(int j=1;j<m;j++)        {            int d,num1=(i-1)*m+j,num2=num1+m+1;            scanf("%d",&d);            ins(num2,num1,d);            //ins(num1,num2,d);        }    }    st=1;ed=n*m;    int ans=0;    while(build()==true)     {        //printf("ok\n");        ans+=work(st,MAX);    }    printf("%d",ans);}

1 0