zoukankan      html  css  js  c++  java
  • [Hnoi2013]消毒

    显然选择的区域有一维要是1,其他维要最大
    相当于问最少切多少个面才能覆盖所有点
    a*b*c<=5000
    那么一定有一个小于等于17
    枚举这一维切不切,跑二分图即可

    TLE代码千万别复制

    # include <bits/stdc++.h>
    # define IL inline
    # define RG register
    # define Fill(a, b) memset(a, b, sizeof(a))
    # define Copy(a, b) memcpy(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(5010), __(1e6 + 10);
    
    IL ll Read(){
        RG char c = getchar(); RG ll x = 0, z = 1;
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    int a, b, c, x[_], y[_], z[_], n, ans;
    int fst[_], nxt[__], to[__], cnt, match[_], vis[_], id;
    
    IL void Add(RG int u, RG int v){  to[cnt] = v; nxt[cnt] = fst[u]; fst[u] = cnt++;  }
    
    IL bool Dfs(RG int u){
        for(RG int e = fst[u]; e != -1; e = nxt[e]){
            if(vis[to[e]] == id) continue;
            vis[to[e]] = id;
            if(match[to[e]] == -1 || Dfs(match[to[e]])){
                match[to[e]] = u;
                return 1;
            }
        }
        return 0;
    }
    
    IL int Calc(RG int S){
        Fill(fst, -1); cnt = 0; Fill(match, -1);
        for(RG int i = 1; i <= n; ++i) if(S & (1 << (z[i] - 1))) Add(x[i], y[i]);
        RG int Ans = c;
        for(; S; S -= S & -S) --Ans;
        for(RG int i = 1; i <= a; ++i) ++id, Ans += Dfs(i);
        return Ans;
    }
    
    int main(RG int argc, RG char* argv[]){
        RG int T = Read();
        while(T--){
            n = 0; a = Read(); b = Read(); c = Read();
            for(RG int i = 1; i <= a; ++i)
                for(RG int j = 1; j <= b; ++j)
                    for(RG int k = 1; k <= c; ++k)
                        if(Read()) x[++n] = i, y[n] = j, z[n] = k;
            if(a < b && a < c){
                swap(a, c);
                for(RG int i = 1; i <= n; ++i) swap(x[i], z[i]);
            }
            else if(b < a && b < c){
                swap(b, c);
                for(RG int i = 1; i <= n; ++i) swap(y[i], z[i]);
            }
            ans = c;
            for(RG int i = 0, S = 1 << c; i < S; ++i) ans = min(ans, Calc(i));
            printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    idea自动整理代码
    idea生成一个类的get/set/toStirng/构造函数等等方法
    idea生成一个java类Class
    解决eclipse不能下载最新的maven仓库中的jar包
    如何解决eclipse控制台信息显示不全
    tomcat-jdbc连接池配置
    三步教你安装微软系统,使用uiso制作U盘启动盘
    好用的java反编译 eclipse插件
    SpringBoot常用应用属性配置表
    SpringBoot的配置文件
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206313.html
Copyright © 2011-2022 走看看