题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3140

题意:最近在生物实验室工作的小T遇到了大麻烦。 由于实验室最近升级的缘故,他的分格实验皿是一个长方体,其尺寸为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的长方体区域进行消毒时,只需要使用min(x,y,z)单位的F试剂。F试剂的价格不菲,这可难倒了小 T。现在请你告诉他,最少要用多少单位的F试剂。

思路:首先由于a*b*c<=5000,则min(a,b,c)最大为17。我们不妨设a最小,那么答案肯定不超过a,至少可以1*b*c这样消毒。但是这样不是最优的。我们用2^a枚举哪些使用 1*b*c来消毒的,然后剩下的用a*1*c和a*b*1的来进行消毒。那么对于某个格子(i,j,k),其要么被a*1*c要么被a*b*1来消毒,只有两种情况,因此建立二分图,求最小顶点覆盖即可。

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <map>
#include <ctype.h>
#include <time.h>

#define abs(x) ((x)>=0?(x):-(x))
#define i64 long long
#define u32 unsigned int
#define u64 unsigned long long
#define clr(x,y) memset(x,y,sizeof(x))
#define CLR(x) x.clear()
#define ph(x) push(x)
#define pb(x) push_back(x)
#define Len(x) x.length()
#define SZ(x) x.size()
#define PI acos(-1.0)
#define sqr(x) ((x)*(x))
#define MP(x,y) make_pair(x,y)
#define EPS 1e-6

#define FOR0(i,x) for(i=0;i<x;i++)
#define FOR1(i,x) for(i=1;i<=x;i++)
#define FOR(i,a,b) for(i=a;i<=b;i++)
#define FORL0(i,a) for(i=a;i>=0;i--)
#define FORL1(i,a) for(i=a;i>=1;i--)
#define FORL(i,a,b)for(i=a;i>=b;i--)

#define rush() int CC;for(scanf("%d",&CC);CC--;)
#define Rush(n)  while(scanf("%d",&n)!=-1)
using namespace std;

void RD(int &x){scanf("%d",&x);}
void RD(i64 &x){scanf("%lld",&x);}
void RD(u64 &x){scanf("%I64u",&x);}
void RD(u32 &x){scanf("%u",&x);}
void RD(double &x){scanf("%lf",&x);}
void RD(int &x,int &y){scanf("%d%d",&x,&y);}
void RD(i64 &x,i64 &y){scanf("%lld%lld",&x,&y);}
void RD(u32 &x,u32 &y){scanf("%u%u",&x,&y);}
void RD(double &x,double &y){scanf("%lf%lf",&x,&y);}
void RD(double &x,double &y,double &z){scanf("%lf%lf%lf",&x,&y,&z);}
void RD(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);}
void RD(i64 &x,i64 &y,i64 &z){scanf("%lld%lld%lld",&x,&y,&z);}
void RD(u32 &x,u32 &y,u32 &z){scanf("%u%u%u",&x,&y,&z);}
void RD(char &x){x=getchar();}
void RD(char *s){scanf("%s",s);}
void RD(string &s){cin>>s;}

void PR(int x) {printf("%d\n",x);}
void PR(int x,int y) {printf("%d %d\n",x,y);}
void PR(i64 x) {printf("%lld\n",x);}
void PR(i64 x,i64 y) {printf("%lld %lld\n",x,y);}
void PR(u32 x) {printf("%u\n",x);}
void PR(u64 x) {printf("%llu\n",x);}
void PR(double x) {printf("%.2lf\n",x);}
void PR(double x,double y) {printf("%.5lf %.5lf\n",x,y);}
void PR(char x) {printf("%c\n",x);}
void PR(char *x) {printf("%s\n",x);}
void PR(string x) {cout<<x<<endl;}

void upMin(int &x,int y) {if(x>y) x=y;}
void upMin(i64 &x,i64 y) {if(x>y) x=y;}
void upMin(double &x,double y) {if(x>y) x=y;}
void upMax(int &x,int y) {if(x<y) x=y;}
void upMax(i64 &x,i64 y) {if(x<y) x=y;}
void upMax(double &x,double y) {if(x<y) x=y;}

const int mod=1000000007;
const i64 inf=((i64)1)<<60;
const double dinf=1000000000000000000.0;
const int INF=100000000;
const int N=5005;

struct node
{
    int x,y,next;
};

node edges[N];
int head[N],e;

int n,m,r;
int K;
int X,Y;

void Add(int x,int y,int z)
{
    if(n<=m&&n<=r)
    {
        edges[e].x=y;
        edges[e].y=z;
        edges[e].next=head[x];
        head[x]=e++;
    }
    else if(m<=n&&m<=r)
    {
        edges[e].x=x;
        edges[e].y=z;
        edges[e].next=head[y];
        head[y]=e++;
    }
    else
    {
        edges[e].x=x;
        edges[e].y=y;
        edges[e].next=head[z];
        head[z]=e++;
    }
}

int get()
{
    char c=getchar();
    while(!isdigit(c)) c=getchar();
    return c-'0';
}

struct Node
{
    int v,next;
};

Node edges1[N<<4];
int head1[N],e1;

void add(int u,int v)
{
    edges1[e1].v=v;
    edges1[e1].next=head1[u];
    head1[u]=e1++;
}

void build(int u)
{
    int i,x,y;
    for(i=head[u];i!=-1;i=edges[i].next)
    {
        x=edges[i].x;
        y=edges[i].y;
        add(x,y);
    }
}

int visit[N],XX;
int match[N];

int DFS(int u)
{
    int i,v;
    for(i=head1[u];i!=-1;i=edges1[i].next)
    {
        v=edges1[i].v;
        if(XX!=visit[v])
        {
            visit[v]=XX;
            if(match[v]==-1||DFS(match[v]))
            {
                match[v]=u;
                return 1;
            }
        }
    }
    return 0;
}

int Match()
{
    int ans=0,i;
    FOR0(i,Y) match[i]=-1;
    FOR0(i,X)
    {
        XX++;
        if(DFS(i)) ans++;
    }
    return ans;
}

int cal(int st)
{
    int ans=0,i;
    for(i=0;i<X;i++) head1[i]=-1;
    e1=0;
    FOR0(i,K)
    {
        if(st&(1<<i)) ans++;
        else build(i);
    }
    return ans+Match();
}

int main()
{
    rush()
    {
        clr(head,-1); e=0; RD(n,m,r);
        int i,j,k;
        FOR0(i,n) FOR0(j,m) FOR0(k,r)
        {
            if(get()) Add(i,j,k);
        }
        if(n<=m&&n<=r) K=n,X=m,Y=r;
        else if(m<=n&&m<=r) K=m,X=n,Y=r;
        else K=r,X=n,Y=m;
        int ans=INF;
        FOR0(i,(1<<K)) upMin(ans,cal(i));
        PR(ans);
    }
}

  

BZOJ 3140 消毒(最小顶点覆盖)的更多相关文章

  1. [BZOJ 3140] 消毒

    Link: BZOJ 3140 传送门 Solution: 挺好的一道暴力题 首先发现可以每次贪心选择宽度为1的一面,即$1*x*y,1*x*z,1*y*z$ 那么对于与该面垂直的面,相当于解决了一行 ...

  2. POJ2226 Muddy Fields 二分匹配 最小顶点覆盖 好题

    在一个n*m的草地上,.代表草地,*代表水,现在要用宽度为1,长度不限的木板盖住水, 木板可以重叠,但是所有的草地都不能被木板覆盖. 问至少需要的木板数. 这类题的建图方法: 把矩阵作为一个二分图,以 ...

  3. poj 3041 Asteroids (最大匹配最小顶点覆盖——匈牙利模板题)

    http://poj.org/problem?id=3041 Asteroids Time Limit: 1000MS   Memory Limit: 65536K Total Submissions ...

  4. hdoj 1150 Machine Schedule【匈牙利算法+最小顶点覆盖】

    Machine Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  5. HDU ACM 1054 Strategic Game 二分图最小顶点覆盖?树形DP

    分析:这里使用树形DP做. 1.最小顶点覆盖做法:最小顶点覆盖 == 最大匹配(双向图)/2. 2.树形DP: dp[i][0]表示i为根节点,而且该节点不放,所需的最少的点数. dp[i][1]表示 ...

  6. hdu1054(最小顶点覆盖)

    传送门:Strategic Game 题意:用尽量少的顶点来覆盖所有的边. 分析:最小顶点覆盖裸题,最小顶点覆盖=最大匹配数(双向图)/2. #include <cstdio> #incl ...

  7. hdu 1150 Machine Schedule(最小顶点覆盖)

    pid=1150">Machine Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/327 ...

  8. poj2594最小顶点覆盖+传递闭包

    传递闭包最开始是在Floyd-Warshall算法里面出现的,当时这算法用的很少就被我忽视了.. 传递闭包是指如果i能到达k,并且k能到达j,那么i就能到达j Have you ever read a ...

  9. hdu1151有向图的最小顶点覆盖

    有向图的最小路径覆盖=V-二分图最大匹配. Consider a town where all the streets are one-way and each street leads from o ...

随机推荐

  1. Nginx开启gzip压缩功能

    在Nginx安装完成之后,我们可以开启Gzip压缩功能,这里Nginx默认只能对text/html类型的文件进行压缩.下面的指令为开启Gzip的指令: gzip on; gzip_http_versi ...

  2. Linux C C语言库的创建和调用

    C语言库的创建和调用 简介: 假如,你有一个庞大的工程,代码量达到数百兆甚至是数G,你经常会遇到好多重复或常用的地方.每次使用到这些地方时如果都重新写一份基本相同的代码,这当然可以,不过这样会大大地降 ...

  3. 从OGRE,GAMEPLAY3D,COCOS2D-X看开源

    OGRE,大家都很熟悉咯. 说到这一点真的有点好笑,我见过很多人说认识OGRE,但是却不知道D3D和OPENGL是什么东东的,可能是我的笑点真的很低,反正是莫名喜感.前天在COCOS2D-X的一个群里 ...

  4. mysql数据库备份及恢复命令mysqldump,source的用法

    还原一个数据库:mysql -h localhost -u root -p123456 www<c:/www.sql 备份一个数据库:mysqldump -h localhost -u root ...

  5. HIVE Transform using 用法

    select TRANSFORM(*, *, *) using 'python filter.py' as (*, *, *) from t_1 HIVE支持pipe操作,将select出来的字段,用 ...

  6. SVN--下载、安装VisualSVN server 服务端和 TortoiseSVN客户端

    前言: 在http://www.cnblogs.com/xiaobaihome/archive/2012/03/20/2407610.html的博客中已经很详细地介绍了SVN的服务器--VisualS ...

  7. SQL SERVER其它函数

    本篇文章还是学习<程序员的SQL金典>内容的记录,此次将讲解的是SQL SERVER常用的其它函数.(其它数据库这里就不罗列了,想看更多的可以关注<程序员的SQL金典>). 具 ...

  8. hibernate4.0中SessionFactory的创建

    创建SessionFactory 首先创建Configuration对象,主要方式是: new Configuration().configure() 默认情况下Hibernate会去classPat ...

  9. asp.net mvc4 使用KindEditor文本编辑器

    最近做项目要用文本编辑器,编辑器好多种,这里介绍KindEditor在asp.net mvc4中的使用方法. 一.准备工作: 1.下载KindEditor.去官网:http://www.kindsof ...

  10. uva 10205 模拟

    模拟题 题目描述挺长的.... #include <cstdio> #include <cstdlib> #include <cmath> #include < ...