bzoj 1001

没有什么是一个BFS或一个DFS解决不了的;如果有,那就两个一起。

裸的最小割,dinic算法水过。

注意时间比较紧,要加一些优化,比如到不了T的边就把它的dis赋值为0。

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000001,maxe=6000001;
int read(){
    char c; while(!isdigit(c=getchar())); int x=c-'0';
    while(isdigit(c=getchar())) x=x*10+c-'0'; return x;
}
struct edge{
    int v,c;
    edge(){}
    edge(int v,int c):v(v),c(c){}
}e[maxe];
int now=0,hed[maxn],nex[maxe];
void add(int u,int v,int c){
    e[++now]=edge(v,c);
    nex[now]=hed[u];
    hed[u]=now;
}
int q[maxn],d[maxn];
int bfs(int n,int m){
    int h=0,t=0;
    memset(d,0,sizeof d);
    q[t++]=1; d[1]=1;
    while(h<t){
        int fr=q[h++];
        for(int i=hed[fr];i!=-1;i=nex[i])
            if(e[i].c>0 && !d[e[i].v])
                d[e[i].v]=d[fr]+1,q[t++]=e[i].v;
    }
    return d[n*m];
}
int dfs(int o,int n,int m,int w){
    if(o==n*m) return w;
    int t=0;
    for(int i=hed[o];i!=-1 && w;i=nex[i])
        if(e[i].c>0 && d[e[i].v]==d[o]+1){
            int k=dfs(e[i].v,n,m,min(w,e[i].c));
            w-=k; e[i].c-=k;
            t+=k; e[i^1].c+=k;
        }
    if(!t) d[o]=0;
    return t;
}
int dinic(int n,int m){
    int ans=0;
    while(bfs(n,m)) ans+=dfs(1,n,m,2e9);
    return ans;
}
int main(){
    memset(hed,-1,sizeof hed);
    int n=read(),m=read();
    for(int i=1;i<=n;i+=1)
        for(int j=1;j<m;j+=1){
            int c=read();
            add((i-1)*m+j,(i-1)*m+j+1,c);
            add((i-1)*m+j+1,(i-1)*m+j,c);
        }
    for(int i=1;i<n;i+=1)
        for(int j=1;j<=m;j+=1){
            int c=read();
            add((i-1)*m+j,i*m+j,c);
            add(i*m+j,(i-1)*m+j,c);
        }
    for(int i=1;i<n;i+=1)
        for(int j=1;j<m;j+=1){
            int c=read();
            add((i-1)*m+j,i*m+j+1,c);
            add(i*m+j+1,(i-1)*m+j,c);
        }
    printf("%d",dinic(n,m));
    return 0;
}

 

posted @ 2017-10-23 11:21  或是七一  阅读(127)  评论(0编辑  收藏  举报