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;
    }
     
  • 相关阅读:
    模式识别之svm()---支持向量机svm 简介1995
    机器视觉之相关资源--- 计算机视觉相关的部分测试数据集和源码站点
    包的引入,不要引入自己目录下的。
    内省对象 用的少,被BeanUtils代替
    使用增强for循环遍历集合的时候操作集合的问题?
    Integer 内部实现
    eclipse常用快捷键
    java 运行时环境和编译器环境
    js 随机变换图片
    js 事件点击 显示 隐藏
  • 原文地址:https://www.cnblogs.com/wangdongkai/p/5616624.html
Copyright © 2011-2022 走看看