• HDU3605:Escape(状态压缩+最大流)


    Escape

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

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=3605

    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

    题意:

    给出n个人,m个星球,每个人都有自己能去的星球,每个星球都有一定的容量,问是否所有人都能到这m个星球上面去。

    题解:

    注意这里人数有1e5,而m不超过10。如果我们直接建边跑最大流,边数可能为1e6,这样肯定会超时的。

    我们注意到m很小,那么会想到对状态进行压缩(如果之前接触过这类题)。

    虽然人数很多,但是最多有2^10种状态,所以我们可以将1e5个点压缩为1024个点,这样再来建图就能在时间、空间上有较大的优化。

    压缩后的每个点表示对这m个星球意愿的状态,1代表能去,0代表不能。

    细节见代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <iostream>
    #define INF 99999999
    using namespace std;
    typedef long long ll;
    const int N = 2000, M = 50000;
    int n,m,cnt,tot,t;
    int peo[N],head[N],d[N];
    
    struct Edge{
        int v,next,c;
    }e[M];
    void adde(int u,int v,int c){
        e[tot].v=v;e[tot].c=c;e[tot].next=head[u];head[u]=tot++;
        e[tot].v=u;e[tot].c=0;e[tot].next=head[v];head[v]=tot++;
    }
    int bfs(){
        memset(d,0,sizeof(d));d[0]=1;
        queue <int > q;q.push(0);
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=head[u];i!=-1;i=e[i].next){
                int v=e[i].v;
                if(e[i].c>0 && !d[v]){
                    d[v]=d[u]+1;
                    q.push(v);
                }
            }
        }
        return d[t]!=0;
    }
    int dfs(int s,int a){
        if(s==t || a==0) return a;
        int flow=0,f;
        for(int i=head[s];i!=-1;i=e[i].next){
            int v=e[i].v;
            if(d[v]!=d[s]+1) continue ;
            f=dfs(v,min(a,e[i].c));
            if(f>0){
                e[i].c-=f;
                e[i^1].c+=f;
                flow+=f;
                a-=f;
                if(a==0) break;
            }
        }
        if(!flow) d[s]=-1;
        return flow;
    }
    int Dinic(){
        int flow=0;
        while(bfs()) flow+=dfs(0,INF);
        return flow;
    }
    int main(){
        while(scanf("%d%d",&n,&m)!=EOF){
            cnt=tot=0;memset(head,-1,sizeof(head));
            memset(peo,0,sizeof(peo));
            for(int i=1;i<=n;i++){
                int x = 0;
                for(int j=1,op;j<=m;j++){
                    x<<=1;
                    scanf("%d",&op);
                    x+=op;
                }
                if(!peo[x]) cnt++;
                peo[x]++;
            }
            t=cnt+m+1;
            for(int i=1;i<=m;i++){
                int c;
                scanf("%d",&c);
                adde(cnt+i,t,c);
            }
            int p=0;
            for(int i=0;i<(1<<m);i++){
                if(!peo[i]) continue ;
                p++;
                adde(0,p,peo[i]);
                for(int j=0;j<m;j++)
                    if(i&(1<<j)) adde(p,m-j+cnt,peo[i]);
            }
            int ans = Dinic();
            if(ans==n) puts("YES");
            else puts("NO");
        }
        return 0;
    }
  • 相关阅读:
    NXOPEN二次开发CAM Operation转OperationBuilder对加工操作修改一些进给速度参数
    NX二次开发MFC对话框自己重绘Button控件(提升美观度)重写DrawItem方法(已完结)
    NX二次开发使用SendMessage给NX窗口发送消息最小化
    NX二次开发调内部函数将对象设置为全局选择(设为高亮选中状态,在选择列表里)
    NX二次开发UFUN输入一个点,距离,矢量方向,获得另外一个点的坐标UF_VEC3_affine_comb
    NX二次开发UFUN获得NX的窗口句柄UF_UI_get_default_parent
    vuetiger机抽奖组件(转)
    浅谈module.exports与exports,export与export default的区别
    解决echarts控制台警告:There is a chart instance already initialize on the dom
    maven版本管理
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10124699.html
Copyright © 2020-2023  润新知