zoukankan      html  css  js  c++  java
  • HDU 3605 最大流+状态压缩

    Escape

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 9920    Accepted Submission(s): 2372


    Problem Description
    2012 If this is the end of the world how to do? I do not know how. But now scientists have found that some stars, who can live, but some people do not fit to live some of the planet. Now scientists want your help, is to determine what all of people can live in these planets.
     
    Input
    More set of test data, the beginning of each data is n (1 <= n <= 100000), m (1 <= m <= 10) n indicate there n people on the earth, m representatives m planet, planet and people labels are from 0. Here are n lines, each line represents a suitable living conditions of people, each row has m digits, the ith digits is 1, said that a person is fit to live in the ith-planet, or is 0 for this person is not suitable for living in the ith planet.
    The last line has m digits, the ith digit ai indicates the ith planet can contain ai people most..
    0 <= ai <= 100000
     
    Output
    Determine whether all people can live up to these stars
    If you can output YES, otherwise output NO.
     
    Sample Input
    1 1
    1
    1
    2 2
    1 0
    1 0
    1 1
     
    Sample Output
    YES
    NO
     
    Source
     题意:
    有n个人,m个星球,开展移民计划,给出每个人能够去的星球和每个星球能够容纳的人的数量,问所有的人是否都能够移民成功。
    输入n,m
    输入n行,每行m个数,1表示此人能够去这个星球,0表示此人不能去这个星球
    输入m个数表示每个星球能够容纳的人的数量。
    代码:
    //这题的n是1e5,直接建图最大流不论是时间还是内存都不行。因为最多只有10个星球所以当n很大时这n个人中
    //必然会有人能去的星球的种类是一样的,这样就可以把每人归为一类,最多(1<<10)-1种人,这样压缩一下最运行最大流
    //看最大流是否等于n。源点连向(1<<m)-1类容量为这一类的人的数量,(1<<m)-1类连向m个星球容量为这一类的人的数量
    //m个星球连向汇点容量为星球能够容纳的人数。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    const int maxn=2100;
    const int inf=0x7fffffff;
    int mp[maxn];
    struct Edge{
        int from,to,cap,flow;
        Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
    };
    struct Dinic{
        int n,m,s,t;
        vector<Edge>edges;
        vector<int>g[maxn];
        bool vis[maxn];
        int d[maxn];
        int cur[maxn];
        void init(int n){
            this->n=n;
            for(int i=0;i<n;i++) g[i].clear();
            edges.clear();
        }
        void Addedge(int from,int to,int cap){
            edges.push_back(Edge(from,to,cap,0));
            edges.push_back(Edge(to,from,0,0));//反向弧
            m=edges.size();
            g[from].push_back(m-2);
            g[to].push_back(m-1);
        }
        bool Bfs(){
            memset(vis,0,sizeof(vis));
            queue<int>q;
            q.push(s);
            d[s]=0;
            vis[s]=1;
            while(!q.empty()){
                int x=q.front();q.pop();
                for(int i=0;i<(int)g[x].size();i++){
                    Edge &e=edges[g[x][i]];
                    if(!vis[e.to]&&e.cap>e.flow){
                        vis[e.to]=1;
                        d[e.to]=d[x]+1;
                        q.push(e.to);
                    }
                }
            }
            return vis[t];
        }
        int Dfs(int x,int a){
            if(x==t||a==0) return a;
            int flow=0,f;
            for(int&i=cur[x];i<(int)g[x].size();i++){
                Edge &e=edges[g[x][i]];
                if(d[x]+1==d[e.to]&&(f=Dfs(e.to,min(a,e.cap-e.flow)))>0){
                    e.flow+=f;
                    edges[g[x][i]^1].flow-=f;
                    flow+=f;
                    a-=f;
                    if(a==0) break;
                }
            }
            return flow;
        }
        int Maxflow(int s,int t){
            this->s=s;this->t=t;
            int flow=0;
            while(Bfs()){
                memset(cur,0,sizeof(cur));
                flow+=Dfs(s,inf);
            }
            return flow;
        }
    }dc;
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)==2){
            int M=(1<<m)-1;
            dc.init(M+m+2);
            int x;
            memset(mp,0,sizeof(mp));
            for(int i=1;i<=n;i++){
                int sta=0;
                for(int j=0;j<m;j++){
                    scanf("%d",&x);
                    sta|=(x<<j);
                }
                mp[sta]++;
            }
            for(int i=1;i<=M;i++){
                dc.Addedge(0,i,mp[i]);
                for(int j=0;j<m;j++){
                    if(i&(1<<j)) dc.Addedge(i,j+1+M,mp[i]);
                }
            }
            for(int i=1;i<=m;i++){
                scanf("%d",&x);
                dc.Addedge(M+i,M+m+1,x);
            }
            if(n==dc.Maxflow(0,M+m+1)) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    技术人员如何创业《四》- 打造超强执行力团队(转载)
    技术人员如何创业《一》—— 产品及想法(转载)
    一页纸商业计划书 (Business Plan) 模板(转载)
    公司项目架构的演变过程
    腾讯云CentOS 6.6安装 Nginx
    创业公司一年工作总结
    启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099的解决办法
    windows下使用批处理脚本实现多个版本的JDK切换
    Java后端WebSocket的Tomcat实现
    微信开发学习总结(三)——开发微信公众号的最基本功能——普通消息的接收和回复
  • 原文地址:https://www.cnblogs.com/--ZHIYUAN/p/6929175.html
Copyright © 2011-2022 走看看