fzu 1686 神龙的难题

来源:互联网 发布:网络上的诈骗方法 编辑:程序博客网 时间:2024/04/27 23:11

 http://acm.fzu.edu.cn/problem.php?pid=1686

DLX重复覆盖,大小为n1*m1的矩阵为行,每个怪物为列

# include <math.h># include <stdio.h># include <string.h># include <stdlib.h># include <algorithm># include <iostream># include <string># include <queue># include <stack># include <map># include <set># include <vector># include <cstring># include <list># include <ctime># define For(i,a)   for((i)=0;i<(a);(i)++)# define MAX(x,y)   ((x)>(y)? (x):(y))# define MIN(x,y)   ((x)<(y)? (x):(y))# define MEM(a)     (memset((a),0,sizeof(a)))# define MEME(a)    (memset((a),-1,sizeof(a)))# define MEMX(a)    (memset((a),0x7f,sizeof(a)))using namespace std;typedef long long           ll      ;typedef unsigned long long  ull     ;typedef unsigned int        uint    ;typedef unsigned char       uchar   ;#define N 260#define M 260int U[N*M],R[N*M],L[N*M],D[N*M];int S[M],H[N],C[N*M];int head,size,ans;void build(int r,int c){    S[c]++; C[size]=c;    U[size]=U[c]; D[U[c]]=size;    D[size]=c; U[c]=size;    if(H[r]==-1) H[r]=R[size]=L[size]=size;    else    {        L[size]=L[H[r]]; R[L[H[r]]]=size;        R[size]=H[r]; L[H[r]]=size;    }    size++;}void remove(int &c){    for(int i=D[c];i!=c;i=D[i])    {        L[R[i]]=L[i];        R[L[i]]=R[i];    }}void resume(int &c){    for(int i=U[c];i!=c;i=U[i])    {        L[R[i]]=i;        R[L[i]]=i;    }}int h(){    int i,j,k,ret=0;    char vis[M];    MEM(vis);    for(i=R[head];i!=head;i=R[i])    {        if(vis[i]==0)        {            ret++;vis[i]=1;            for(j=D[i];j!=i;j=D[j])                for(k=R[j];k!=j;k=R[k])                    vis[C[k]]=1;        }    }    return ret;}void dfs(int dep){    int i,j,c,min;    if(R[head]==head)    {        if(dep<ans) ans=dep;        return ;    }    if(dep+h()>=ans)        return ;    for(i=R[head],min=10000000;i!=head;i=R[i])        if(S[i]<min)        {            min=S[i]; c=i;        }    remove(c);    L[R[c]]=L[c]; R[L[c]]=R[c];    for(i=D[c];i!=c;i=D[i])    {        L[R[i]]=i;R[L[i]]=i;        for(j=R[i];j!=i;j=R[j])            remove(j);        dfs(dep+1);        for(j=L[i];j!=i;j=L[j])            resume(j);        L[R[i]]=L[i];R[L[i]]=R[i];    }    L[R[c]]=c; R[L[c]]=c;    resume(c);}int a[20][20];int main(){    int n,m,n1,m1;    int i,j,k,r,p;    while(scanf("%d%d",&n,&m)!=EOF)    {        k=1;MEM(a);        for(i=1;i<=n;i++)            for(j=1;j<=m;j++)            {                scanf("%d",&p);                if(p==1) a[i][j]=k++;            }        scanf("%d%d",&n1,&m1);        for(i=0;i<k;i++)        {            R[i]=i+1;L[i]=i-1;            U[i]=i; D[i]=i;            S[i]=0;        }        R[k-1]=0;L[0]=k-1;        MEME(H);        head=0;size=k;        p=0;        for(i=1;i<=n-n1+1;i++)            for(j=1;j<=m-m1+1;j++)            {                for(k=i;k<=i+n1-1;k++)                    for(r=j;r<=j+m1-1;r++)                        if(a[k][r]!=0)                            build(p,a[k][r]);                p++;            }        ans=1000000;        dfs(0);        printf("%d\n",ans);    }    return 0;}


 

原创粉丝点击