zoukankan      html  css  js  c++  java
  • HDU 3605 Escape (最大流)

    Escape

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

    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
     
     
    分析
    很裸的最大流,但是点特别多,我用SAP超时了。
    我们可以看到有m个0和1,因此可以用状态压缩,将一个人的信息压缩成一个二进制数,这样就只有1024+m+2的点了
     
    但是还有特别坑的,还好网上看到了学长的题解,HDU要将G++改为C++才能AC,不然读数据就会TLE
    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    using namespace std;
    //****************************************************
    //最大流模板  SAP算法
    //邻接表形式
    //******************************************************
    const int MAXN = 100000+110;//点数的最大值
    const int MAXM = 4000110;//边数的最大值
    const int INF = 0x3f3f3f3f;
    
    struct Node
    {
        int from,to,next;
        int cap;
    }edge[MAXM];
    int tol;
    int head[MAXN];
    int dep[MAXN];
    int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y
    
    int n;//n是总的点的个数,包括源点和汇点
    
    void init()
    {
        tol=0;
        memset(head,-1,sizeof(head));
    }
    
    void addedge(int u,int v,int w)
    {
        edge[tol].from=u;
        edge[tol].to=v;
        edge[tol].cap=w;
        edge[tol].next=head[u];
        head[u]=tol++;
        edge[tol].from=v;
        edge[tol].to=u;
        edge[tol].cap=0;
        edge[tol].next=head[v];
        head[v]=tol++;
    }
    void BFS(int start,int end)
    {
        memset(dep,-1,sizeof(dep));
        memset(gap,0,sizeof(gap));
        gap[0]=1;
        int que[MAXN];
        int front,rear;
        front=rear=0;
        dep[end]=0;
        que[rear++]=end;
        while(front!=rear)
        {
            int u=que[front++];
            if(front==MAXN)front=0;
            for(int i=head[u];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(dep[v]!=-1)continue;
                que[rear++]=v;
                if(rear==MAXN)rear=0;
                dep[v]=dep[u]+1;
                ++gap[dep[v]];
            }
        }
    }
    int SAP(int start,int end)
    {
        int res=0;
        BFS(start,end);
        int cur[MAXN];
        int S[MAXN];
        int top=0;
        memcpy(cur,head,sizeof(head));
        int u=start;
        int i;
        while(dep[start]<n)
        {
            if(u==end)
            {
                int temp=INF;
                int inser;
                for(i=0;i<top;i++)
                   if(temp>edge[S[i]].cap)
                   {
                       temp=edge[S[i]].cap;
                       inser=i;
                   }
                for(i=0;i<top;i++)
                {
                    edge[S[i]].cap-=temp;
                    edge[S[i]^1].cap+=temp;
                }
                res+=temp;
                top=inser;
                u=edge[S[top]].from;
            }
            if(u!=end&&gap[dep[u]-1]==0)//出现断层,无增广路
              break;
            for(i=cur[u];i!=-1;i=edge[i].next)
               if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1)
                 break;
            if(i!=-1)
            {
                cur[u]=i;
                S[top++]=i;
                u=edge[i].to;
            }
            else
            {
                int min=n;
                for(i=head[u];i!=-1;i=edge[i].next)
                {
                    if(edge[i].cap==0)continue;
                    if(min>dep[edge[i].to])
                    {
                        min=dep[edge[i].to];
                        cur[u]=i;
                    }
                }
                --gap[dep[u]];
                dep[u]=min+1;
                ++gap[dep[u]];
                if(u!=start)u=edge[S[--top]].from;
            }
        }
        return res;
    }
    
    int num[1025];
    int bit[11];
    
    int main()
    {
        int N,M;
        int v;
        bit[0]=1;
        for(int i=1;i<=10;i++) bit[i]=bit[i-1]*2;
        while(scanf("%d%d",&N,&M)!=EOF){
            if(N==0||M==0) break;
            int st,ed;
            init();
            st=0,ed=N+M+1;
            n=N+M+2;
            memset(num,0,sizeof(num));
            for(int i=1;i<=N;i++){
                int tmp=0;
                for(int j=0;j<M;j++){  //状态压缩
                    scanf("%d",&v);
                    tmp+=v*bit[j];
                }
                num[tmp]++;
            }
            for(int i=0;i<1024;i++){
                if(num[i]==0) continue;
                addedge(i+1+M,ed,num[i]);
                for(int j=0;j<10;j++)
                    if(i&bit[j])
                       addedge(j+1,i+1+M,INF);
            }
            for(int i=1;i<=M;i++){
                scanf("%d",&v);
                addedge(st,i,v);
            }
            int ans=SAP(st,ed);
            if(ans==N) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
     
  • 相关阅读:
    索引器
    拆箱,装箱,枚举,结构
    题解报告(CDUT暑期集训——第二场)
    题解报告(CDUT暑期集训——第一场)
    第十一届四川省程序设计竞赛赛后感(电科两日游
    ZOJ4108 Fibonacci in the Pocket
    ZOJ4107 Singing Everywhere
    ZOJ4106 Lucky 7 in the Pocket
    ZOJ4105 Abbreviation
    ZOJ4104 Sequence in the Pocket
  • 原文地址:https://www.cnblogs.com/wangdongkai/p/5616624.html
Copyright © 2011-2022 走看看