Description
最近在生物实验室工作的小T遇到了大麻烦。 由于实验室最近升级的缘故,他的分格实验皿是一个长方体,其尺寸为abc,a、b、c
均为正整数。为了实验的方便,它被划分为abc个单位立方体区域,每个单位立方体尺寸 为111。用(i,j,k)标识一个单位立方体,1
≤i≤a,1≤j≤b,1≤k≤c。这个实验皿已经很久没有人用了,现在,小T被导师要求将其中一些单位立方体区域进
行消毒操作(每个区域可以被重复消毒)。而由于严格的实验要求,他被要求使用一种特定 的F试剂来进行消毒。
这种F试剂特别奇怪,每次对尺寸为xyz的长方体区域(它由xyz个单位立方体组
成)进行消毒时,只需要使用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)需要被消毒。输入保证满足abc≤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,未重测.
题解
wori拍扁到二维居然都不是很会做啊…
容易发现 对于任意一种解法,我们都可以把它分割成 或者 的矩阵
所以二维就可以直接 二分图匹配了
三维的话…
发现最小的那一维肯定不会超过17
又发现在这种情况下肯定是每次消毒一个截面
暴力枚举最小那一维怎么消毒
然后就全部拍扁到二维,二分图玩一玩就行了…
有点卡常…
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#include<set>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define pll pair<long long,long long>
#define pii pair<int,int>
using namespace std;
inline int read()
{
int f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int stack[20];
inline void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(!x){putchar('0');return;}
int top=0;
while(x)stack[++top]=x%10,x/=10;
while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(int x){write(x);putchar('\n');}
const int MAXN=10005;
const int MAXM=500005;
struct edge{int x,y,next;}a[MAXM];int len,last[MAXN];
void ins(int x,int y){len++;a[len].x=x;a[len].y=y;a[len].next=last[x];last[x]=len;}
int chw[MAXN],tim,match[MAXN],ok[MAXN],t1;
bool findmuniu(int x)
{
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(chw[y]!=tim)
{
chw[y]=tim;
if(ok[y]!=t1||findmuniu(match[y]))
{
match[y]=x;ok[y]=t1;
return true;
}
}
}
return false;
}
//vector<int> vec[20][5005];//z x y
int A,B,C,cl[20],ans;
struct pt
{
int x,y,z;
pt(){}
pt(int _x,int _y,int _z){x=_x;y=_y;z=_z;}
}g[MAXN];int le;
int fir[20];
void solve(int s1)
{
if(A<B)
{
len=0;for(int i=1;i<=A;i++)last[i]=0;
for(int i=1;i<=19;i++)if(fir[i]<=1e9&&!cl[i])
{
for(int j=fir[i];j<=le;j++)
{
if(g[j].z!=i)break;
ins(g[j].x,g[j].y+A);
}
}
// for(int i=1;i<=le;i++)if(!cl[g[i].z])ins(g[i].x,g[i].y+A);
t1++;
int re=0;
for(int i=1;i<=A;i++)
{
tim++;
if(findmuniu(i))re++;
if(re+s1>=ans)return ;
}
ans=min(ans,re+s1);
}
else
{
len=0;for(int i=1;i<=B;i++)last[i]=0;
for(int i=1;i<=19;i++)if(fir[i]<=1e9&&!cl[i])
{
for(int j=fir[i];j<=le;j++)
{
if(g[j].z!=i)break;
ins(g[j].y,g[j].x+B);
}
}
// for(int i=1;i<=le;i++)if(!cl[g[i].z])ins(g[i].y,g[i].x+B);
t1++;
int re=0;
for(int i=1;i<=B;i++)
{
tim++;
if(findmuniu(i))re++;
if(re+s1>=ans)return ;
}
ans=min(ans,re+s1);
}
}
void dfs(int k,int to)
{
if(to>ans)return ;
if(k==C+1){solve(to);return ;}
dfs(k+1,to);
cl[k]=1;dfs(k+1,to+1);cl[k]=0;
}
bool cmp(pt n1,pt n2){return n1.z<n2.z;}
int main()
{
// freopen("10.in","r",stdin);
int T=read();
while(T--)
{
A=read();B=read();C=read();int gg=min(A,min(B,C));le=0;
if(gg==A)
{
for(int i=1;i<=A;i++)for(int j=1;j<=B;j++)for(int k=1;k<=C;k++)
{
int c=read();
if(c)g[++le]=pt(k,j,i);
}
int u1=C,u2=B,u3=A;
A=u1;B=u2;C=u3;
}
else if(gg==B)
{
// for(int i=1;i<=A;i++)for(int j=1;j<=B;j++)for(int k=1;k<=C;k++)vec[j][i].push_back(read());
for(int i=1;i<=A;i++)for(int j=1;j<=B;j++)for(int k=1;k<=C;k++)
{
int c=read();
if(c)g[++le]=pt(i,k,j);
}
int u1=A,u2=C,u3=B;
A=u1;B=u2;C=u3;
}
else
{
for(int i=1;i<=A;i++)for(int j=1;j<=B;j++)for(int k=1;k<=C;k++)
{
int c=read();
if(c)g[++le]=pt(i,j,k);
}
int u1=A,u2=B,u3=C;
A=u1;B=u2;C=u3;
}
// for(int i=1;i<=C;i++)
// {
// for(int j=1;j<=A;j++)
// {
// for(int k=0;k<B;k++)pr1(vec[i][j][k]);
// puts("");
// }
// puts("");
// }
sort(g+1,g+1+le,cmp);
memset(fir,63,sizeof(fir));
for(int i=1;i<=le;i++)fir[g[i].z]=min(fir[g[i].z],i);
ans=999999999;dfs(1,0);
pr2(ans);
}
return 0;
}