poj3740 Easy Finding DLX

来源:互联网 发布:每天最佳健身时间 知乎 编辑:程序博客网 时间:2024/06/12 01:47

    跟上题差不多,还是一个01矩阵,问是否可以选出若干行使得每列恰有一个1。模型都给建好了,直接建表搜就可以了..

#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>using namespace std;typedef long long ll;const int maxn=320*320;struct DLX{    int col[maxn],row[maxn],ans[maxn];    int S[maxn],H[maxn];    int size,cnt;    int U[maxn],R[maxn],D[maxn],L[maxn];    void remove(int c)    {        L[R[c]]=L[c];        R[L[c]]=R[c];        for (int i=D[c]; i!=c; i=D[i])        {            for (int j=R[i]; j!=i; j=R[j])            {                U[D[j]]=U[j];                D[U[j]]=D[j];                --S[col[j]];            }        }    }    void resume(int c)    {        L[R[c]]=c;        R[L[c]]=c;        for (int i=U[c]; i!=c; i=U[i])        {            for (int j=R[i]; j!=i; j=R[j])            {                U[D[j]]=j;                D[U[j]]=j;                ++S[col[j]];            }        }    }    bool dance(int k)    {        int c=R[0];        if (c==0)        {            cnt=k;            return true;        }        for (int i=R[0]; i!=0; i=R[i])        {            if (S[c]>S[i]) c=i;        }        remove(c);        for (int i=D[c]; i!=c; i=D[i])        {            ans[k]=row[i];            for (int j=R[i]; j!=i; j=R[j]) remove(col[j]);            if (dance(k+1)) return true;            for (int j=R[i]; j!=i; j=R[j]) resume(col[j]);        }        resume(c);        return false;    }    void init(int n)    {        for (int i=0; i<=n; i++)        {            S[i]=0;            L[i]=i-1;            R[i]=i+1;            U[i]=D[i]=i;        }        L[0]=n;        R[n]=0;        size=n+1;        memset(H,-1,sizeof H);    }    void link(int x,int y)    {        ++S[col[size]=y];        row[size]=x;        D[size]=D[y];        U[D[y]]=size;        U[size]=y;        D[y]=size;        if (H[x]<0) H[x]=L[size]=R[size]=size;        else        {            R[size]=R[H[x]];            L[R[H[x]]]=size;            L[size]=H[x];            R[H[x]]=size;        }        size++;    }}dlx;int n,m,k,num;int main(){//    freopen("in.txt","r",stdin);    while (~scanf("%d%d",&m,&n))    {        dlx.init(n);        for (int i=1; i<=m; i++)        for (int j=1; j<=n; j++)        {            scanf("%d",&k);            if (k)            {                dlx.link(i,j);            }        }        if (dlx.dance(0))        {            puts("Yes, I found it");        }        else puts("It is impossible");    }    return 0;}


0 0