zoukankan      html  css  js  c++  java
  • BZOJ 1458: 士兵占领 最大流

    判断有没有解:让所有没有障碍的格子都放一个士兵.   

    那么,题中要求最少放几个士兵,就是最多拿走几个士兵.  

    而由于行和列对士兵个数都是由要求的,这就规定了拿走的士兵的上界.  

    跑一个最大流来求就行了.  

    code: 

    #include <cstdio> 
    #include <queue>
    #include <algorithm> 
    #include <cstring>  
    #include <vector>
    #define N 302   
    #define inf 10005 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;   
    int s,t; 
    int vis[N]; 
    int d[N]; 
    int gr[N][N]; 
    int M[N],a[N],b[N];             
    struct Edge { 
        int u,v,c; 
        Edge(int u=0,int v=0,int c=0):u(u),v(v),c(c){}  
    }; 
    queue<int>q;  
    vector<Edge>edges;   
    vector<int>G[N];  
    void add(int u,int v,int c) {
        edges.push_back(Edge(u,v,c)); 
        edges.push_back(Edge(v,u,0));   
        int o=edges.size();   
        G[u].push_back(o-2); 
        G[v].push_back(o-1);       
    }     
    int dfs(int x,int cur) {  
        if(x==t) return cur;   
        int an=0,flow=0; 
        for(int i=0;i<G[x].size();++i) {
            Edge e=edges[G[x][i]];   
            if(e.c>0&&d[e.v]==d[x]+1) {      
                an=dfs(e.v,min(cur,e.c));    
                if(an) {
                    cur-=an; 
                    flow+=an;             
                    edges[G[x][i]].c-=an; 
                    edges[G[x][i]^1].c+=an;     
                    if(!cur) break;    
                } 
            }
        }
        return flow;  
    }
    int bfs() {    
        memset(vis,0,sizeof(vis)); 
        d[s]=0; 
        vis[s]=1; 
        q.push(s); 
        while(!q.empty()) {
            int u=q.front(); 
            q.pop();  
            for(int i=0;i<G[u].size();++i) {
                if(edges[G[u][i]].c>0) {
                    int v=edges[G[u][i]].v;   
                    if(!vis[v]) {
                        vis[v]=1; 
                        d[v]=d[u]+1;   
                        q.push(v);   
                    }
                }
            }
        } 
        return vis[t];  
    }    
    int maxflow() { 
        int re=0; 
        while(bfs()) {
            re+=dfs(s,inf);   
        } 
        return re; 
    }
    int main() { 
        // setIO("input");         
        int i,j,n,m,k;      
        scanf("%d%d%d",&n,&m,&k);      
        for(i=1;i<=n;++i)  scanf("%d",&a[i]); 
        for(i=1;i<=m;++i)  scanf("%d",&b[i]);  
        for(i=1;i<=k;++i) {
            int x,y; 
            scanf("%d%d",&x,&y);         
            gr[y][x]=1;      
        }
        for(i=1;i<=n;++i) { 
            int re=0; 
            for(j=1;j<=m;++j) { 
                re+=gr[i][j];  
            }   
            M[i]=m-re-a[i];   
        }   
        for(i=1;i<=m;++i) {
            int re=0; 
            for(j=1;j<=n;++j) {
                re+=gr[j][i];  
            }
            M[i+n]=n-re-b[i];   
        }
        for(i=1;i<=n+m;++i)  {
            if(M[i]<0)   {
                printf("JIONG!
    "); 
                return 0; 
            }
        } 
        s=0,t=n+m+1;  
        for(i=1;i<=n;++i) {      
            add(s,i,M[i]);   
            for(j=n+1;j<=n+m;++j) {
                add(i,j,1);   
            }
        }    
        for(i=n+1;i<=n+m;++i) {
            add(i,t,M[i]);  
        }   
        printf("%d
    ",m*n-k-maxflow());   
        return 0; 
    }
    

      

  • 相关阅读:
    iscsi: 多路径
    Paxos算法分析
    ceph实践: 搭建环境
    ocfs2: 搭建环境
    设计模式:Context模式
    Ceph剖析:Leader选举
    Ceph剖析:定时器safetimer的实现
    nfs:环境搭建
    Ceph剖析:数据分布之CRUSH算法与一致性Hash
    Linux命令小结:crontab/netstat/iostat/sar
  • 原文地址:https://www.cnblogs.com/guangheli/p/12063362.html
Copyright © 2011-2022 走看看