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

    Description

    最近在生物实验室工作的小T遇到了大麻烦。 
    由于实验室最近升级的缘故,他的分格实验皿是一个长方体,其尺寸为a*b*c,a、b、c 均为正整数。为了实验的方便,它被划分为a*b*c个单位立方体区域,每个单位立方体尺寸
    为1*1*1。用(i,j,k)标识一个单位立方体,1 ≤i≤a,1≤j≤b,1≤k≤c。这个实验皿已经很久没有人用了,现在,小T被导师要求将其中一些单位立方体区域进 行消毒操作(每个区域可以被重复消毒)。而由于严格的实验要求,他被要求使用一种特定 的F试剂来进行消毒。 这种F试剂特别奇怪,每次对尺寸为x*y*z的长方体区域(它由x*y*z个单位立方体组 成)进行消毒时,只需要使用min{x,y,z}单位的F试剂。F试剂的价格不菲,这可难倒了小 T。现在请你告诉他,最少要用多少单位的F试剂。(注:min{x,y,z}表示x、y、z中的最小 者。) 

    Input

    第一行是一个正整数D,表示数据组数。接下来是D组数据,每组数据开头是三个数a,b,c表示实验皿的尺寸。接下来会出现a个b 行c列的用空格隔开的01矩阵,0表示对应的单位立方体不要求消毒,1表示对应的单位立方体需要消毒;例如,如果第1个01矩阵的第2行第3列为1,则表示单位立方体(1,2,3)需要被消毒。输入保证满足a*b*c≤5000,T≤3。

    Output

    仅包含D行,每行一个整数,表示对应实验皿最少要用多少单位 的F试剂。

    Sample Input

    1
    4 4 4
    1 0 1 1
    0 0 1 1
    0 0 0 0
    0 0 0 0
    0 0 1 1
    1 0 1 1
    0 0 0 0
    0 0 0 0
    0 0 0 0
    0 0 0 0
    1 0 0 0
    0 0 0 0
    0 0 0 0
    0 0 0 0
    0 0 0 0
    1 0 0 0

    Sample Output

    3

    HINT 

    对于区域(1,1,3)-(2,2,4)和(1,1,1)-(4,4,1)消毒,分别花费2个单位和1个单位的F试剂。2017.5.26新加两组数据By Leoly,未重测.

    正解:搜索+二分图匹配。

    我们考虑弱化一下条件,假设只有两维,这道题应该怎么做呢?

    很显然,我们每次都会选择$[a,m]$或$[n,b]$的矩形进行覆盖,换句话说,我们每次就是覆盖一行或者一列。

    那么二维的情况就是二分图最小点覆盖,那么就等于最大匹配,于是我们直接把行向列连边,跑匈牙利就行了。

    三维的情况似乎不那么好做了,但是我们注意到$a*b*cleq 5000$,也就是说,最小的那个数$leq 17$。

    我们可以直接把$c$变成最小值,然后爆搜每一层是否直接消毒,直接消毒代价为$1$。

    我们把剩下还没有消毒的层拼在一起,那么它们消毒的代价肯定是行或列。那么我们跑一遍匈牙利就行了。

    复杂度$O(2^{c}*a*b)$。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define pos(i,j,k) ((i-1)*b*c+(j-1)*c+k)
     6 
     7 using namespace std;
     8 
     9 int e[5005][5005],vis[5005],lk[5005],sz[5005],d[5005],a,b,c,cnt,ans;
    10 
    11 il int gi(){
    12   RG int x=0,q=1; RG char ch=getchar();
    13   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    14   if (ch=='-') q=-1,ch=getchar();
    15   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    16   return q*x;
    17 }
    18 
    19 il int dfs(RG int x){
    20   for (RG int i=1;i<=c;++i){
    21     if (!e[x][i] || vis[i]==cnt) continue; vis[i]=cnt;
    22     if (!lk[i] || dfs(lk[i])) return lk[i]=x,1;
    23   }
    24   return 0;
    25 }
    26 
    27 il void dfs(RG int x,RG int tot){
    28   if (x>a){
    29     for (RG int i=1;i<=c;++i) vis[i]=lk[i]=0; cnt=0;
    30     for (RG int i=1;i<=b;++i) ++cnt,tot+=dfs(i);
    31     ans=min(ans,tot); return;
    32   }
    33   if (tot>=ans) return;
    34   for (RG int i=1;i<=b;++i)
    35     for (RG int j=1;j<=c;++j) e[i][j]+=d[pos(x,i,j)];
    36   dfs(x+1,tot);
    37   for (RG int i=1;i<=b;++i)
    38     for (RG int j=1;j<=c;++j) e[i][j]-=d[pos(x,i,j)];
    39   if (sz[x]) dfs(x+1,tot+1); return;
    40 }
    41 
    42 il void work(){
    43   a=gi(),b=gi(),c=gi(),memset(d,0,sizeof(d)),memset(sz,0,sizeof(sz));
    44   if (a<=b && a<=c){
    45     for (RG int i=1;i<=a;++i)
    46       for (RG int j=1;j<=b;++j)
    47     for (RG int k=1;k<=c;++k) d[pos(i,j,k)]=gi();
    48   } else if (b<=a && b<=c){
    49     swap(a,b);
    50     for (RG int i=1;i<=b;++i)
    51       for (RG int j=1;j<=a;++j)
    52     for (RG int k=1;k<=c;++k) d[pos(j,i,k)]=gi();
    53   } else{
    54     swap(a,c);
    55     for (RG int i=1;i<=c;++i)
    56       for (RG int j=1;j<=b;++j)
    57     for (RG int k=1;k<=a;++k) d[pos(k,j,i)]=gi();
    58   }
    59   for (RG int i=1;i<=a;++i)
    60     for (RG int j=1;j<=b;++j)
    61       for (RG int k=1;k<=c;++k) sz[i]+=d[pos(i,j,k)];
    62   ans=1<<30,dfs(1,0),printf("%d
    ",ans); return;
    63 }
    64 
    65 int main(){
    66 #ifndef ONLINE_JUDGE
    67   freopen("clear.in","r",stdin);
    68   freopen("clear.out","w",stdout);
    69 #endif
    70   RG int T=gi();
    71   while (T--) work();
    72   return 0;
    73 }
  • 相关阅读:
    【cocos2d-x 024】 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
    【cocos2d-x 024】 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
    socket 通信代码,单线程
    socket 通信代码,单线程
    socket 通信代码,单线程
    使用Cocos Studio 创建帧动画
    使用Cocos Studio 创建帧动画
    使用Cocos Studio 创建帧动画
    sscanf函数用法详解
    (OK) firefox
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7953548.html
Copyright © 2011-2022 走看看