• 狼和羊的故事


    依照题目要求,即是不能从2流到1去,那么就是最小割。

    从2向0,1连边,从0向0,1连边,然后跑最大流。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 1e9
    const int maxn=105;
    const int maxm=5*1e4+5;
    int n,m,a[maxn][maxn];
    int beg[maxm],nex[maxm],to[maxm],w[maxm],e;
    inline void add(int x,int y,int z){
        nex[e]=beg[x];beg[x]=e;
        to[e]=y;w[e]=z;e++;
    }
    inline int read(){
        int x=0;char c=getchar();
        while(c<'0'||c>'9')c=getchar();
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        return x;
    }
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    inline int get(int x,int y){return (x-1)*m+y;}
    int dep[maxm];
    queue<int>q;
    inline int bfs(){
        memset(dep,0x3f,sizeof(dep));
        while(!q.empty())q.pop();
        dep[0]=0;q.push(0);
        while(!q.empty()){
            int x=q.front();
            q.pop();
            for(int i=beg[x];~i;i=nex[i]){
                int t=to[i];
                if(w[i]&&dep[t]>maxn){
                    dep[t]=dep[x]+1;
                    q.push(t);
                }
            }
        }
        return dep[n*m+1]<maxn;
    }
    inline int dfs(int x,int lim){
        if(x==n*m+1||!lim)return lim;
        int ans=0;
        for(int i=beg[x];~i;i=nex[i]){
            int t=to[i];
            if(w[i]&&dep[t]==dep[x]+1){
                int f=dfs(t,min(w[i],lim));
                w[i]-=f;w[i^1]+=f;
                lim-=f;ans+=f;
            }
        }
        return ans;
    }
    int main(){
        memset(beg,-1,sizeof(beg));
        n=read();m=read();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                a[i][j]=read();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                if(a[i][j]==1){
                    add(get(i,j),n*m+1,inf);
                    add(n*m+1,get(i,j),0);
                    continue;
                }
                if(a[i][j]==2){
                    add(0,get(i,j),inf);
                    add(get(i,j),0,0);
                }
                for(int k=0;k<4;k++){
                    int xx=i+dx[k];
                    int yy=j+dy[k];
                    if(xx<1||yy<1||xx>n||yy>m)
                        continue;
                    if(a[xx][yy]!=2){
                        add(get(i,j),get(xx,yy),1);
                        add(get(xx,yy),get(i,j),0);
                    }
                }
            }
        int maxflow=0;
        while(bfs())maxflow+=dfs(0,inf);
        printf("%d
    ",maxflow);
        return 0;
    } 

    深深地感到自己的弱小。

  • 相关阅读:

    二分查找法
    LeetCode-Two Sum III
    LeetCode-Add and Search Word
    LeetCode-Longest Substring with At Least K Repeating Characters
    LeetCode-Rearrange String k Distance Apart
    LeetCode-Game of Life
    LeetCode-Walls and Gates
    LeetCode-Water and Jug Problem
    LeetCode-Inorder Successor in BST
  • 原文地址:https://www.cnblogs.com/syzf2222/p/12567771.html
Copyright © 2020-2023  润新知