zoukankan      html  css  js  c++  java
  • [BZOJ 1412] 狼与羊的故事

    Link:

    BZOJ 1412 传送门

    Solution:

    非常明显的最小割模型:

    将所有点分成两个互不相邻的点集,且要求代价最小

    建图:

    $<S,sheep,INF>$

    $<wolf,T,INF>$

    $<sheep,wolf/ground,1>$、$<ground,wolf/sheep/ground,1>$

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    const int MAXN=10005,MAXM=40005,INF=1<<27;
    namespace Max_Flow
    {
        int head[MAXN],S,T,level[MAXN],iter[MAXN],tot=-1;
        struct edge{int nxt,to,cap;}e[MAXM<<2];
        
        void add_edge(int from,int to,int cap)
        {
            e[++tot].nxt=head[from];e[tot].to=to;e[tot].cap=cap;head[from]=tot;
            e[++tot].nxt=head[to];e[tot].to=from;e[tot].cap=0;head[to]=tot;
        }    
        bool bfs()
        {
            memset(level,-1,sizeof(level));
            queue<int> q;q.push(S);level[S]=0;
            while(!q.empty())
            {
                int u=q.front();q.pop();
                for(int i=head[u];i!=-1;i=e[i].nxt)
                    if(e[i].cap && level[e[i].to]==-1)
                        level[e[i].to]=level[u]+1,q.push(e[i].to);
            }
            return (level[T]!=-1);
        }    
        int dfs(int v,int f)
        {
            if(v==T) return f;
            int ret=0;
            for(int &i=iter[v];i!=-1;i=e[i].nxt)
            {
                if(level[e[i].to]==level[v]+1 && e[i].cap)
                {
                    int d=dfs(e[i].to,min(f,e[i].cap));
                    e[i].cap-=d;e[i^1].cap+=d;
                    f-=d;ret+=d;if(!f) break;
                }
            }
            return ret;
        }    
        int Dinic()
        {
            int ret=0;
            while(bfs())
            {
                for(int i=0;i<MAXN;i++) iter[i]=head[i];
                ret+=dfs(S,INF);
            }
            return ret;
        }
    }
    
    int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
    int n,m,dat[105][105];
    
    int main()
    {
        using namespace Max_Flow;
        S=0;T=10001;memset(head,-1,sizeof(head));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&dat[i][j]);
        
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if(dat[i][j]==1) add_edge(S,(i-1)*m+j,INF);
                if(dat[i][j]==2){add_edge((i-1)*m+j,T,INF);continue;}
                for(int k=0;k<4;k++)
                {
                    int fx=i+dx[k],fy=j+dy[k];
                    if(fx<1||fx>n||fy<1||fy>m) continue;
                    if(dat[i][j]!=1 || dat[fx][fy]!=1)
                        add_edge((i-1)*m+j,(fx-1)*m+fy,1);
                }
            }
        printf("%d",Dinic());
        return 0;
    }
  • 相关阅读:
    python 入门
    element 使用问题总结
    element dialog 弹窗 解决每次先加载上一次数据再加载本次数据问题
    JS 对变量进行全文替换方法
    react源码解析10.commit阶段
    react源码解析9.diff算法
    react源码解析8.render阶段
    react源码解析7.Fiber架构
    react源码解析6.legacy模式和concurrent模式
    react源码解析5.jsx&核心api
  • 原文地址:https://www.cnblogs.com/newera/p/9238008.html
Copyright © 2011-2022 走看看