Easy Finding

· · 个人记录

Easy Finding

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
int read()
{
    char ch=getchar();int h=0,t=1;
    while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
    if(ch=='-') t=-1,ch=getchar();
    while(ch>='0'&&ch<='9') h=h*10+ch-'0',ch=getchar();
    return h*t;
}
int n,m,flag;
namespace DLX
{
    const int N=5000;
    int n,m,p,h[N],s[N];
    int l[N],r[N],u[N],d[N];
    int row[N],col[N];
    void init(int nn,int mm)
    {
        n=nn;m=mm;flag=0;
        for(int i=0;i<=m;i++)
            r[i]=i+1,l[i]=i-1,u[i]=d[i]=i;
        r[m]=0;l[0]=p=m;
        memset(h,-1,sizeof(h));
        memset(s,0,sizeof(s));
    }
    void link(int R,int C)
    {
        s[C]++;p++;
        row[p]=R;col[p]=C;

        u[p]=u[C];d[p]=C;
        d[u[C]]=p;u[C]=p;
//      u[p]=C;d[p]=d[C];
//      u[d[C]]=p;d[C]=p;
        if(h[R]<0) h[R]=l[p]=r[p]=p;
        else
        {
            r[p]=h[R];l[p]=l[h[R]];
            r[l[h[R]]]=p;l[h[R]]=p;
        }
    }
    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=d[C];i!=C;i=d[i])
            for(int j=r[i];j!=i;j=r[j])
                u[d[j]]=j,d[u[j]]=j,s[col[j]]++;

    }
    void dance()
    {
        if(r[0]==0||flag) {flag=1;return;}
        int w=r[0];
        for(int i=r[w];i!=w;i=r[i])
            if(s[i]<s[w]&&s[i]) w=i;
        remove(w);
        for(int i=d[w];i!=w;i=d[i])
        {
            for(int j=r[i];j!=i;j=r[j]) remove(col[j]);
            dance(); if(flag) return;
            for(int j=r[i];j!=i;j=r[j]) resume(col[j]);
        }
        resume(w);
    }
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        DLX::init(n,m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(read()) DLX::link(i,j);
        DLX::dance();
        flag?puts("Yes, I found it"):puts("It is impossible");
    }
}