HNOI 2013 bzoj 3140 消毒

来源:互联网 发布:怎么关闭软件自动更新 编辑:程序博客网 时间:2024/04/28 22:00

暴力一维,剩下两维做一个最小点覆盖

要注意memset的复杂度问题!

/**************************************************************    Problem: 3140    User: Clare    Language: C++    Result: Accepted    Time:1160 ms    Memory:1468 kb****************************************************************/ #include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <vector>using namespace std; #define N 5010#define INF 0x3f3f3f3f int a,b,c;int n,K,Ans,Vis_tot,cnt;int Left[N],Vis[N],C[22];struct Edge{    int to,next;}edge[N*2];int head[N],tot;struct Node{    int x,y,z;}A[N]; inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}    return x*f;} void Addedge(int u,int v){    tot++;edge[tot].next=head[u];edge[tot].to=v;head[u]=tot;} bool Find(int x){    for(int i=head[x];i;i=edge[i].next)    {        int v=edge[i].to;        if(Vis[v]!=Vis_tot)        {            Vis[v]=Vis_tot;            if(!Left[v]||Find(Left[v]))            {                Left[v]=x;                return true;            }        }    }    return false;}  void Search(int k){    int Sum=0;    for(int i=0;i<a;i++)        if(k&C[i])            Sum++;    if(Sum>=Ans)        return;    tot=0;    for(int i=1;i<=b;i++)        head[i]=0;    for(int i=1;i<=c;i++)        Left[i]=0;    for(int i=1;i<=cnt;i++)    {        if(!(k&C[A[i].x-1]))            Addedge(A[i].y,A[i].z);    }    for(int i=1;i<=b;i++)    {        Vis_tot++;        if(Find(i))            Sum++;        if(Sum>=Ans)            return;    }    Ans=Sum;} int main(){    C[0]=1;    for(int i=1;i<=20;i++)        C[i]=C[i-1]<<1;    int T=read();    while(T--)    {        cnt=0;        a=read();b=read();c=read();        for(int i=1;i<=a;i++)        {            for(int j=1;j<=b;j++)            {                for(int k=1;k<=c;k++)                {                    int x=read();                    if(x)                        A[++cnt]=(Node){i,j,k};                }            }        }        if(a>b)        {            swap(a,b);            for(int i=1;i<=cnt;i++)                swap(A[i].x,A[i].y);        }        if(a>c)        {            swap(a,c);            for(int i=1;i<=cnt;i++)                swap(A[i].x,A[i].z);        }        Ans=INF;        for(int i=0;i<C[a];i++)            Search(i);        printf("%d\n",Ans);    }    return 0;}


0 0
原创粉丝点击