zoukankan      html  css  js  c++  java
  • p2598 [ZJOI2009]狼和羊的故事

    传送门

    分析

    起点向狼连边,羊向终点连边,边权均为inf

    每个点向它四联通的点连边权萎1的边

    跑最小割即可

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    #include<queue>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    const int dx[] = {1,-1,0,0};
    const int dy[] = {0,0,1,-1};
    const int inf = 1e9+7;
    int n,m,s,t,head[2000100],to[2000100],nxt[2000100],w[2000100],ano[2000100],cnt,level[2000100],cur[2000100];
    inline void add(int x,int y,int z){
        nxt[++cnt]=head[x];
        head[x]=cnt;
        to[cnt]=y;
        w[cnt]=z;
        ano[cnt]=cnt+1;
        nxt[++cnt]=head[y];
        head[y]=cnt;
        to[cnt]=x;
        w[cnt]=0;
        ano[cnt]=cnt-1;
    }
    inline int id(int x,int y){return (x-1)*m+y;}
    inline void go(int x,int y){
        for(int i=0;i<4;i++){
          if(dx[i]+x<=0||dx[i]+x>n||dy[i]+y<=0||dy[i]+y>m)continue;
          add(id(x,y),id(dx[i]+x,dy[i]+y),1);
        }
    }
    inline bool bfs(){
        memset(level,-1,sizeof(level));
        queue<int>q;
        level[s]=0;
        q.push(s);
        while(!q.empty()){
          int x=q.front();
          q.pop();
          for(int i=head[x];i;i=nxt[i])
            if(level[to[i]]==-1&&w[i]){
              level[to[i]]=level[x]+1;
              if(to[i]==t)return 1;
              q.push(to[i]);
            }
        }
        return 0;
    }
    inline int dfs(int x,int flow){
        if(x==t||!flow)return flow;
        int res=0;
        cur[x]=head[x];
        for(int i=cur[x];i;i=nxt[i]){
          cur[x]=i;
          if(level[to[i]]==level[x]+1&&w[i]){
              int f=dfs(to[i],min(w[i],flow-res));
              w[i]-=f;
              res+=f;
              w[ano[i]]+=f;
          }
        }
        if(!res)level[x]=-1;
        return res;
    }
    int main(){
        int i,j,k,Ans=0;
        scanf("%d%d",&n,&m);
        s=n*m+1,t=s+1;
        for(i=1;i<=n;i++)
          for(j=1;j<=m;j++){
            scanf("%d",&k);
            if(k==1)add(s,id(i,j),inf);
              else if(k==2)add(id(i,j),t,inf);
            go(i,j);
          }
        while(bfs())while(int a=dfs(s,inf))Ans+=a;
        cout<<Ans;
        return 0;
    }
  • 相关阅读:
    跨页传值另一种方法
    运行nodejs的blog程序遇见问题
    nodejs和mongodb实践
    mongodb数据库实践笔记
    两次分页显示内容——先少后多显示
    Java进阶4表达式中的陷阱
    Java进阶3. 内存回收机制
    Java进阶1. Synchronized 关键字
    Java复习9网路编程
    Java复习8.多线程
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10527189.html
Copyright © 2011-2022 走看看