• 【BZOJ】3140: [Hnoi2013]消毒


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3140


    猜一发(显然)有结论:每次一定选择一个平面,即每次操作对答案的贡献都为$1$

    首先可以考虑二维的情况。

    二维不就是一个经典的最小点覆盖模型么,如果${(x,y)=1}$就把横纵轴上的点分别看为二分图的两边的点,最小点覆盖模型=最大匹配数。

    三维?

    ${a*b*c<=5000}$显然${Maxleft { a,b,c ight }<=17}$
    考虑枚举(搜索)最小的那一维,剩下的直接看(拍)成一个平面当成二维的做即可。


     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<cstring>
     8 using namespace std;
     9 #define maxn 1000100
    10 #define llg long long 
    11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    12 llg n,G,C,K,T,cnt,N,belong[maxn],bj[maxn];
    13 
    14 vector<llg>a[maxn];
    15 
    16 struct node
    17 {
    18     llg x,y,z;
    19 }point[maxn];
    20 
    21 void init()
    22 {
    23     llg x;
    24     cnt=0;
    25     scanf("%lld%lld%lld",&C,&K,&G);
    26     for (llg i=1;i<=C;i++)
    27         for (llg j=1;j<=K;j++)
    28             for (llg k=1;k<=G;k++)
    29             {
    30                 scanf("%lld",&x);
    31                 if (x) point[++cnt]=(node){i,j,k}; 
    32             }
    33 }
    34 
    35 bool find(llg x)
    36 {
    37     llg w=a[x].size(),v;
    38     for (llg i=0;i<w;i++)
    39     {
    40         v=a[x][i];
    41         if (bj[v]) continue;
    42         bj[v]=1;
    43         if (!belong[v] || find(belong[v]))
    44         {
    45             belong[v]=x; belong[x]=v;
    46             return 1;
    47         }
    48     }
    49     return 0;
    50 }
    51 
    52 llg work(llg zt)
    53 {
    54     llg sum=0; N=C+K;
    55     for (llg i=1;i<=N;i++) a[i].clear(),belong[i]=0;
    56     for (llg i=0;i<G;i++) if ((zt&(1<<i))==0) sum++;
    57     for (llg i=1;i<=cnt;i++)
    58         if (zt&(1<<(point[i].z-1)))
    59         {
    60             llg x=point[i].x,y=C+point[i].y;
    61             a[x].push_back(y),a[y].push_back(x);
    62         }
    63     for (llg i=1;i<=N;i++) 
    64         if (!belong[i])
    65         {
    66             for (llg j=1;j<=N;j++) bj[j]=0; 
    67             if (find(i)) sum++;
    68         }
    69     return sum;
    70 }
    71 
    72 int main()
    73 {
    74     yyj("clear");
    75     cin>>T;
    76     while (T--)
    77     {
    78         init();
    79         if (C<G) {swap(G,C); for (llg i=1;i<=cnt;i++) swap(point[i].x,point[i].z); }
    80         if (K<G) {swap(G,K); for (llg i=1;i<=cnt;i++) swap(point[i].y,point[i].z); }
    81         llg ans=(llg)1e16;
    82         for (llg i=0;i<(1<<G);i++) 
    83             ans=min(work(i),ans);
    84         printf("%lld
    ",ans);
    85     }
    86     return 0;
    87 }
    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    解决android.os.NetworkOnMainThreadException
    android 模拟器对应键盘快捷键
    Android上解析Json格式数据
    命令行的由来
    Linux测网速
    cacti
    判断端口是否开放
    Linux中运行c程序,与系统打交道
    python 多线程
    Leetcode 编程训练(转载)
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6434955.html
Copyright © 2020-2023  润新知