zoukankan      html  css  js  c++  java
  • bzoj1412

    从狼向空格或羊剪边,从空格向空格或羊建边,最大流最小割

    最大流dinic打法(这里用了当前弧优化)

    diniv当前弧优化讲解

    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cstring>
    #define maxn 10002
    #define inf 0x3ffffff
    using namespace std;
    int n,m,ans,S,T,cnt,cur[maxn],dep[maxn],head[maxn],nex[maxn<<4],to[maxn<<4],w[maxn<<4],s[102][102];
    int bzx[]={0,1,0,-1},bzy[]={1,0,-1,0};
    inline void read(int &x){
        char ch=getchar();x=0;int f=1;
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        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]=0;head[v]=cnt++;}
    inline int bfs(){
        queue<int>q;while(!q.empty())q.pop();
        memset(dep,0,sizeof dep);dep[S]=1;q.push(S);
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=head[u];~i;i=nex[i]){
                int v=to[i];
                if(w[i]>0 && dep[v]==0){
                    dep[v]=dep[u]+1;
                    q.push(v);
                }
            }
        }
        return dep[T]!=0;
    }
    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(w[i]>0 && dep[v]==dep[u]+1){
                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[u]=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);
        read(n);read(m);S=0;T=n*m+1;
        for(int i=1;i<=n;i++)s[i][0]=s[i][m+1]=-1;
        for(int i=1;i<=m;i++)s[0][i]=s[n+1][i]=-1;
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){
            read(s[i][j]);
            if(s[i][j]==2)addedge(S,(i-1)*m+j,inf);if(s[i][j]==1)addedge((i-1)*m+j,T,inf);
        }
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)for(int k=0;k<4;k++){
            if((s[i][j]==2 ||s[i][j]==0) && (s[i+bzx[k]][j+bzy[k]]==1 || s[i+bzx[k]][j+bzy[k]]==0))addedge((i-1)*m+j,(i+bzx[k]-1)*m+j+bzy[k],1);
        }
        dinic();
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    EF+MVC+Bootstrap 项目实践 Day7
    JS---数组
    OS---华硕笔记本从U盘启动安装系统
    PHP--分页类
    PHP--数据库操作类
    OS---net start mysql 发生系统错误5
    MYSQL---远程连接mysql数据库提示:ERROR 1130的解决办法
    CSS-小谈LV,HA!
    MYSQL---设置存储引擎
    MYSQL---存储引擎
  • 原文地址:https://www.cnblogs.com/MikuKnight/p/9204684.html
Copyright © 2011-2022 走看看