BZOJ 3140 消毒(最小顶点覆盖)
题目链接: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 消毒(最小顶点覆盖)的更多相关文章
- [BZOJ 3140] 消毒
Link: BZOJ 3140 传送门 Solution: 挺好的一道暴力题 首先发现可以每次贪心选择宽度为1的一面,即$1*x*y,1*x*z,1*y*z$ 那么对于与该面垂直的面,相当于解决了一行 ...
- POJ2226 Muddy Fields 二分匹配 最小顶点覆盖 好题
在一个n*m的草地上,.代表草地,*代表水,现在要用宽度为1,长度不限的木板盖住水, 木板可以重叠,但是所有的草地都不能被木板覆盖. 问至少需要的木板数. 这类题的建图方法: 把矩阵作为一个二分图,以 ...
- poj 3041 Asteroids (最大匹配最小顶点覆盖——匈牙利模板题)
http://poj.org/problem?id=3041 Asteroids Time Limit: 1000MS Memory Limit: 65536K Total Submissions ...
- hdoj 1150 Machine Schedule【匈牙利算法+最小顶点覆盖】
Machine Schedule Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDU ACM 1054 Strategic Game 二分图最小顶点覆盖?树形DP
分析:这里使用树形DP做. 1.最小顶点覆盖做法:最小顶点覆盖 == 最大匹配(双向图)/2. 2.树形DP: dp[i][0]表示i为根节点,而且该节点不放,所需的最少的点数. dp[i][1]表示 ...
- hdu1054(最小顶点覆盖)
传送门:Strategic Game 题意:用尽量少的顶点来覆盖所有的边. 分析:最小顶点覆盖裸题,最小顶点覆盖=最大匹配数(双向图)/2. #include <cstdio> #incl ...
- hdu 1150 Machine Schedule(最小顶点覆盖)
pid=1150">Machine Schedule Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/327 ...
- poj2594最小顶点覆盖+传递闭包
传递闭包最开始是在Floyd-Warshall算法里面出现的,当时这算法用的很少就被我忽视了.. 传递闭包是指如果i能到达k,并且k能到达j,那么i就能到达j Have you ever read a ...
- hdu1151有向图的最小顶点覆盖
有向图的最小路径覆盖=V-二分图最大匹配. Consider a town where all the streets are one-way and each street leads from o ...
随机推荐
- Struts之ForwardAction
在Struts中,通过action跳转jsp,但是有时希望仅仅只是跳转页面,而不需要action,这时可以用ForwardAction. 定义一个仅仅是跳转的ForwardAction如下: < ...
- JPA学习---第一节:JPA详解
一.详解 JPA JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据.他的出现主要是 ...
- android studio 中设置apk的版本号
今天在mainfest.xml中设置版本号为2,(代码获取到的版本号无效) android:versionCode="2" android:versionName="2. ...
- MyEclipse2015破解版_MyEclipse 2015 stable 2.0 稳定版 破解日志
前言:在MyEclipse 2015 Stable 1.0下载安装破解日志(http://www.cnblogs.com/wql025/p/5161979.html)一文中,笔者主要讲述了该版本的破解 ...
- $POST数组论证($GET || $COOKIE || $REQUEST 同理)
我觉得还是有多个$_POST 如果只有一个$_POST,那么,多个人[同时]提交的话就不好处理 或者一个$_POST 时间限制(如同时钟周期)处理(不可能,不然响应没这么快) 或者 一个$_POS ...
- 【锋利的JQuery-学习笔记】广告栏
效果图: html: <div id="jnImageroll"> <a href="#nogo" id="JS_imgWrap&q ...
- memory leak
In computer science, a memory leak occurs when a computer program incorrectly manages memory allocat ...
- 青鸟 王云鹏老师写的SqlHelper 泛型方法,反射,支持实体类
1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5: ...
- hdu1301Jungle Roads
http://acm.hdu.edu.cn/showproblem.php?pid=1301 最小生成树模板题 #include<iostream> #include<stdio.h ...
- cojs 简单的01串 题解报告
题意显然是求n位二进制串中不大于其逆序串,取反串,逆序取反串的所有串按字典序排序后的第k个 由于n很小,k很大所以我们可以考虑逐位确定 问题转化为了求方案数,这显然是可以用数位DP做的 设f[len] ...