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

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3140

    思路:首先我们观察题目只需要使用min{x,y,z}单位的F试剂

    那么我们如果选择一位长度为a,那其他两维直接取到最大即可

    那么题目就相当于问最少切多少个面才能覆盖所有点

    二维的很简单,直接二分图匹配即可(不会的见poj3041)

    http://poj.org/problem?id=3041

    三维的怎么办?

    这时a*b*c<=5000就有用了

    我们2^n枚举最小的一维每层切还是不切(不超过17)

    不切的层再二分图匹配即可

    复杂度有点坑,但还是可以接受的

    千万不要作死用memset

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    const int maxn=5010,inf=1e9,maxm=100010;
    using namespace std;
    struct poi{int x,y,z;}p[maxn];
    int mat[maxn],cnt,cas,pw[20],ans,vis[maxn],pre[maxm],now[maxn],son[maxm],tim,tot,a,b,c;
    void add(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
    bool cmp(poi a,poi b){
    	if (a.x!=b.x) return a.x<b.x;
    	if (a.y!=b.y) return a.y<b.y;
    	return a.z<b.z;
    }
    
    bool dfs(int x){
    	for (int y=now[x];y;y=pre[y]){
    		int v=son[y];
    		if (vis[v]<tim){
    			vis[v]=tim;
    			if (!mat[v]||dfs(mat[v])) return mat[v]=x,1;
    		}
    	}
    	return 0;
    }
    
    void work(int st){
    	int res=0,n=b,m=c;tot=0;
    	for (int i=0;i<a;i++) if (st&pw[i]) res++;
    //	printf("%d
    ",res);
    	if (res>=ans) return;
    	for (int i=1;i<=n;i++) now[i]=0;
    	for (int i=1;i<=m;i++) mat[i]=0;
    	for (int i=1;i<=cnt;i++) if (!(st&pw[p[i].x-1])) add(p[i].y,p[i].z);
    	for (int i=1;i<=n;i++){
    		tim++;
    		if (dfs(i)) res++;
    		if (res>=ans) return;
    	}
    	ans=res;
    }
    
    int main(){
    	scanf("%d",&cas);
    	pw[0]=1;for (int i=1;i<=19;i++) pw[i]=pw[i-1]*2;
    	//for (int i=1;i<=19;i++) printf("pw %d
    ",pw[i]);
    	while (cas--){
    		scanf("%d%d%d",&a,&b,&c),ans=1e9,cnt=0;
    		for (int i=1,op;i<=a;i++) for (int j=1;j<=b;j++) for (int k=1;k<=c;k++){scanf("%d",&op);if (op) p[++cnt]=(poi){i,j,k};}
    		if (b<a){swap(a,b);for (int i=1;i<=cnt;i++) swap(p[i].x,p[i].y);}
    		if (c<a){swap(a,c);for (int i=1;i<=cnt;i++) swap(p[i].x,p[i].z);}
    		sort(p+1,p+1+cnt,cmp);
    		for (int i=0;i<pw[a];i++) work(i);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    


  • 相关阅读:
    多线程---同步函数的锁是this(转载)
    函数
    流程控制
    基本语句和运算
    基本数据库类型
    迷宫问题
    Dungeon Master(逃脱大师)-BFS
    HTML元素常用属性整理
    Java_hutool 发起请求
    jQuery Autocomplete
  • 原文地址:https://www.cnblogs.com/thythy/p/5493487.html
Copyright © 2011-2022 走看看