bzoj 1001

裸的最小割,直接上Dinic算法。结果跑得很慢。

#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000001;
const int maxm=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[maxm];
vector<int> to[maxn];
int n,m,cnt=0,vis[maxn],dis[maxn],q[maxn];
void add(int u,int v,int c){
    e[cnt]=edge(v,c);
    to[u].push_back(cnt++);
}
bool bfs(){
    memset(vis,0,sizeof vis);
    vis[1]=1; int h=0,t=0;
    q[t++]=1;
    while(h<t){
        int fr=q[h++];
        for(int i=0;i<to[fr].size();i+=1)
            if(e[to[fr][i]].c && !vis[e[to[fr][i]].v]){
                vis[e[to[fr][i]].v]=1;
                q[t++]=e[to[fr][i]].v;
                dis[e[to[fr][i]].v]=dis[fr]+1;
            }
    }
    return vis[n*m];
}
int dfs(int o,int f){
    if(o==n*m) return f;
    int res=0;
    for(int i=0;i<to[o].size() && f;i+=1)
        if(e[to[o][i]].c && dis[e[to[o][i]].v]==dis[o]+1){
            int k=dfs(e[to[o][i]].v,min(f,e[to[o][i]].c));
            res+=k; e[to[o][i]].c-=k; e[to[o][i]^1].c+=k; f-=k;
        }
    if(!res) dis[o]=-1;
    return res;
}
int dinic(){
    int ans=0;
    while(bfs()) ans+=dfs(1,2e9);
    return ans;
}
int main(){
    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());
    return 0;
}

 

posted @ 2017-10-12 20:20  失忆的旅行者  阅读(123)  评论(0编辑  收藏  举报