zoukankan      html  css  js  c++  java
  • bzoj千题计划295:bzoj3140: [Hnoi2013]消毒

    http://www.lydsy.com/JudgeOnline/problem.php?id=3140

    如果只有两维,那就是二分图最小点覆盖

    现在是三维,但是a*b*c<=5000,说明最小的那一维不会超过17

    将最小的那一维作为正方形的高

    然后枚举要消哪些层,剩下的层看成一层 做最小点覆盖

    注意卡常

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    
    using namespace std;
    
    #define N 5001
    
    struct node
    {
        int i,j,k;
    }e[N];
    
    bool have[18];
    
    int front[N],to[N],nxt[N],tot;7
    
    int match[N];
    int tim,vis[N];
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    bool go(int u)
    {
        int v;
        for(int i=front[u];i;i=nxt[i])
        {
            v=to[i];
            if(vis[v]!=tim)
            {
                vis[v]=tim;
                if(!match[v] || go(match[v])) 
                {
                    match[v]=u;
                    return true;
                }
            }
        }
        return false;
    }
    
    int count(int x)
    {
        int sum=0;
        while(x) sum+=x&1,x>>=1;
        return sum;
    }
    
    void add(int u,int v)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
    }
    
    int main()
    {
        int T,a,b,c;
        int ty,x;
        int S,cnt; bool tag;
        int ans,now;
        read(T);
        while(T--)
        {
            read(a); read(b); read(c);
            if(a<=b && a<=c) ty=1;
            else if(b<=a && b<=c) ty=2;
            else ty=3;
            memset(have,false,sizeof(have));
            cnt=0;
            for(int i=1;i<=a;++i)
                for(int j=1;j<=b;++j)
                    for(int k=1;k<=c;++k)
                    {
                        read(x);
                        if(!x) continue;
                        cnt++;
                        if(ty==1) e[cnt].i=i,e[cnt].j=j,e[cnt].k=k;
                        if(ty==2) e[cnt].i=j,e[cnt].j=i,e[cnt].k=k;
                        if(ty==3) e[cnt].i=k,e[cnt].j=i,e[cnt].k=j;
                        have[e[cnt].i]=true;
                    }
            if(ty==2) swap(a,b);
            else if(ty==3) swap(b,c),swap(a,b);
            ans=a;
            S=1<<a;
            for(int s=0;s<S;++s)
            {
                tag=true;
                for(int i=1;i<=a && tag;++i)
                    if(1<<i-1&s && !have[i]) tag=false;
                if(!tag) continue;
                now=count(s);
                tot=0;
                memset(front,0,sizeof(*front)*(b+1));
                for(int i=1;i<=cnt;++i)
                    if(!(1<<e[i].i-1&s)) add(e[i].j,e[i].k);
                memset(match,0,sizeof(*match)*(c+1));
                for(int i=1;i<=b;++i)
                {
                    tim++;
                    if(go(i)) now++;
                    if(now>=ans) break;
                }
                ans=ans<=now ? ans : now;
            }
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    AES-GCM算法
    Linux Curl命令
    OpenLDAP
    网络性能测试
    LoadRunner
    XSLT
    dtruss
    删除重复图片
    2018年部门管理的一点总结
    矢量地图方案的进一步探讨
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8610811.html
Copyright © 2011-2022 走看看