[DLX重复覆盖] hdu 3529 Bomberman - Just Search!

来源:互联网 发布:it deserves 编辑:程序博客网 时间:2024/05/12 11:43

题意:

给你N*M的图,*是破坏不了的墙,#是需要你破坏的前,.是可以放炸弹的地方。

每个点只能放一个炸弹,同时放炸弹,炸弹是四个方向无限距离,能被墙挡住。

问你最少放多少个炸弹,能把所以#炸掉。

思路:

对每个.进行编号,以及每个#进行编号。

.为行,#为列建图。

跑DLX重复覆盖即可。

代码:

#include"cstdlib"#include"cstdio"#include"cstring"#include"cmath"#include"queue"#include"algorithm"#include"iostream"#include"map"#include"vector"#define mod 1000000007#define ll long longusing namespace std;#define N 1010*100#define RN 1010#define CN 1010struct DLX{    int n,m,C;    int U[N],D[N],L[N],R[N],Row[N],Col[N];    int H[RN],S[CN],cnt,ans[RN];    void init(int _n,int _m)    {        n=_n;        m=_m;        for(int i=0; i<=m; i++)        {            S[i]=0;            U[i]=D[i]=i;            L[i]=(i==0?m:i-1);            R[i]=(i==m?0:i+1);        }        C=m;        for(int i=1; i<=n; i++) H[i]=-1;    }    void link(int x,int y)    {        C++;        Row[C]=x;        Col[C]=y;        S[y]++;        U[C]=U[y];        D[C]=y;        D[U[y]]=C;        U[y]=C;        if(H[x]==-1) H[x]=L[C]=R[C]=C;        else        {            L[C]=L[H[x]];            R[C]=H[x];            R[L[H[x]]]=C;            L[H[x]]=C;        }    }    void del(int x)    {        for(int i=D[x]; i!=x; i=D[i])        {            R[L[i]]=R[i];            L[R[i]]=L[i];        }    }    void rec(int x)    {        for(int i=U[x]; i!=x; i=U[i])        {            R[L[i]]=i;            L[R[i]]=i;        }    }    int used[CN];    int h()    {        int sum=0;        for(int i=R[0]; i!=0; i=R[i]) used[i]=0;        for(int i=R[0]; i!=0; i=R[i])        {            if(used[i]==0)            {                sum++;                used[i]=1;                for(int j=D[i]; j!=i; j=D[j]) for(int k=R[j]; k!=j; k=R[k]) used[Col[k]]=1;            }        }        return sum;    }    void dance(int x)    {        if(x+h()>=cnt) return ;        if(R[0]==0)        {            cnt=min(cnt,x);            return ;        }        int now=R[0];        for(int i=R[0]; i!=0; i=R[i])        {            if(S[i]<S[now])                now=i;        }        for(int i=D[now]; i!=now; i=D[i])        {            del(i);            for(int j=R[i]; j!=i; j=R[j]) del(j);            dance(x+1);            for(int j=L[i]; j!=i; j=L[j]) rec(j);            rec(i);        }        return ;    }} dlx;char mp[22][22];int num[22][22];int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=-1)    {        int sum=0;        for(int i=0;i<n;i++) scanf("%s",mp[i]);        memset(num,0,sizeof(num));        int cnt=0;        for(int i=0;i<n;i++)        {            for(int j=0;j<m;j++)            {                if(mp[i][j]=='.') sum++;                if(mp[i][j]=='#') num[i][j]=++cnt;            }        }        dlx.init(sum,cnt);        int bh=0;        for(int i=0;i<n;i++)        {            for(int j=0;j<m;j++)            {                if(mp[i][j]!='.') continue;                bh++;                for(int k=1;;k++)                {                    if(mp[i+k][j]=='*') break;                    if(mp[i+k][j]=='#')                    {                        dlx.link(bh,num[i+k][j]);                        break;                    }                }                for(int k=1;;k++)                {                    if(mp[i-k][j]=='*') break;                    if(mp[i-k][j]=='#')                    {                        dlx.link(bh,num[i-k][j]);                        break;                    }                }                for(int k=1;;k++)                {                    if(mp[i][j+k]=='*') break;                    if(mp[i][j+k]=='#')                    {                        dlx.link(bh,num[i][j+k]);                        break;                    }                }                for(int k=1;;k++)                {                    if(mp[i][j-k]=='*') break;                    if(mp[i][j-k]=='#')                    {                        dlx.link(bh,num[i][j-k]);                        break;                    }                }            }        }        dlx.cnt=15*15+100;        dlx.dance(0);        printf("%d\n",dlx.cnt);    }    return 0;}


0 0