• 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;
    }
  • 相关阅读:
    Mysql Explain 详解【转】
    Windows下Gradle安装与配置
    MYSQ创建联合索引,字段的先后顺序,对查询的影响分析
    给.Net 5 Api增加JwtBearer认证
    纸壳CMS 3.3.6发布升级.Net 5
    PL/SQL Developer登入时候报ORA-12638: 身份证明检索失败的解决办法
    Mybatis 日志工厂
    Mybatis 配置解析
    Mybatis 完成增删改查
    Mybatis 简介
  • 原文地址:https://www.cnblogs.com/MikuKnight/p/9204684.html
Copyright © 2020-2023  润新知