bzoj1001

注意双向边正反边容量相同

#include<cstdio>
#include<cstring>
#include<cctype>
#include<queue>
#define maxn 1000005
#define inf 1000000007
using namespace std;
int n,m,S,T,hd,tail,ans,q[maxn],dep[maxn];
int cnt,head[maxn],cur[maxn],nex[maxn*6],to[maxn*6],w[maxn*6];
inline int read(){
    char ch=getchar();int x=0,f=1;
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    return x*=f;
}
inline void addedge(int u,int v,int wi){nex[cnt]=head[u];to[cnt]=v;w[cnt]=wi;head[u]=cnt++;nex[cnt]=head[v];to[cnt]=u;w[cnt]=wi;head[v]=cnt++;}
inline int bfs(){
    hd=0;q[tail=1]=S;
    memset(dep,0,sizeof(dep));dep[S]=1;
    while(hd!=tail){
        int u=q[++hd];
        for(int j=head[u];~j;j=nex[j])if(!dep[to[j]] && w[j]>0){dep[to[j]]=dep[u]+1,q[++tail]=to[j];}
        if(u==T)return 1;
    }
    return dep[T];
}
inline int dfs(int u,int flow){
    if(u==T)return flow;
    int ans=0,x=0;
    for(int &i=cur[u];~i;i=nex[i]){
       int v=to[i];
       if(dep[u]+1==dep[v] && w[i]>0){
        x=dfs(v,min(flow-ans,w[i]));
        w[i]-=x;w[i^1]+=x;
        ans+=x;
        if(ans==flow)return flow;
       }
    }
    if(ans==0)dep[x]=0;
    return ans;
}
inline void dinic(){
    while(bfs()){for(int i=S;i<=T;i++)cur[i]=head[i];ans+=dfs(S,inf);}
}
int main(){
    memset(head,-1,sizeof(head));
    n=read(),m=read();
    S=1,T=n*m;int x;
    for(int i=1;i<=n;i++)for(int j=1;j<m;j++)addedge((i-1)*m+j,(i-1)*m+j+1,read());
    for(int i=1;i<n;i++)for(int j=1;j<=m;j++)addedge((i-1)*m+j,i*m+j,read());
    for(int i=1;i<n;i++)for(int j=1;j<m;j++)addedge((i-1)*m+j,i*m+j+1,read());
    dinic();
    printf("%d",ans);
    return 0;
}

 

posted @ 2018-06-20 19:33  lnyzo  阅读(143)  评论(0编辑  收藏  举报