HDOJ2828-DLX, 重复覆盖小变形

来源:互联网 发布:北京爱知科技有限公司 编辑:程序博客网 时间:2024/05/17 22:55

代码是昨天写的,今天又试着做重复覆盖的DLX,发现根本写不下,出现了重重错误,我还以为我昨天误打误撞的代码很优咧,太自以为是了!这道HDOJ2828也是好题,它比我今天试写的HDOJ3957简单得多,最大的不同不是一个只是求一个YES/NO,另一个求的是最小dfs深度,而是3957的链表数据中的关系比2828复杂,所以dance实现部分的思想都是不一样的~

**尚未成功,菜鸟仍需努力~不想说revolution那个凝重的词。

// 第二个Dancing links,1Y,0ms,暂时排名第五,挺兴奋的!#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int NN=505;const int MM=51000;int n,m,cnt,R[MM],L[MM],U[MM],D[MM],C[MM],H[MM],flag[MM];int S[NN],O[NN],V[NN];void init()//这里的十字链表以灯为列,开关为行{    cnt=n;    for (int i=0; i<=n; i++)    {        D[i]=U[i]=i;        R[i]=i+1;        L[i+1]=i;        S[i]=0;    }    L[0]=n,R[n]=0;    for (int i=1; i<=m; i++) V[i]=0;}void add_link(int i,int j,int t){    C[++cnt]=i;    H[cnt]=j;    S[i]++;    flag[cnt]=t;  //开关状态    D[cnt]=i;    U[cnt]=U[i];    if (V[j]) R[cnt]=V[j],L[cnt]=L[V[j]];    else      R[cnt]=L[cnt]=cnt;    V[j]=cnt;    U[D[cnt]]=cnt;    D[U[cnt]]=cnt;    R[L[cnt]]=cnt;    L[R[cnt]]=cnt;}void remove(int c)//题意不同,这里remove有变,指的是删除c列{    L[R[c]]=L[c];    R[L[c]]=R[c];    for (int i=D[c]; i!=c; i=D[i])    {        L[R[i]]=L[i];        R[L[i]]=R[i];        S[C[i]]--;    }}void resume(int c){    for (int i=U[c]; i!=c; i=U[i])    {        R[L[i]]=i;        L[R[i]]=i;        S[C[i]]++;    }    R[L[c]]=L[R[c]]=c;}bool dance(){    if (!R[0])    {        for (int i=1; i<m; i++) printf(O[i]==1?"ON ":"OFF ");        puts(O[m]==1?"ON":"OFF");        return 1;    }    int c,s=MM,i,j;    for (i=R[0]; i; i=R[i]) if (S[i]<s) s=S[c=i];    if (s==0) return 0; //s==0说明没有开关能使灯c处于ON的状态了        R[L[c]]=R[c]; L[R[c]]=L[c]; //这里只需删去列指针c即可    for (i=D[c]; i!=c; i=D[i])    {        O[H[i]]=flag[i];//记录答案        for (int j=R[i]; j!=i; j=R[j])        {            if (flag[j]==flag[i]) remove(C[j]);            else D[U[j]]=D[j],U[D[j]]=U[j],S[C[j]]++;//这里没写S[C[j]]--时也过了,想想确实不影响正确性        }        if (dance()) return 1;        for (int j=L[i]; j!=i; j=L[j])        {            if (flag[j]==flag[i]) resume(C[j]);            else U[D[j]]=j,D[U[j]]=j,S[C[j]]--;        }    }    R[L[c]]=c; L[R[c]]=c;//恢复列指针c    return 0;}int main(){    int k,x;    char str[5];    while (~scanf("%d%d",&n,&m))    {        init();        for (int i=1; i<=n; i++)        {            scanf("%d",&k);            while (k--)            {                scanf("%d%s",&x,&str);                if (str[1]=='N') add_link(i,x,1);                else             add_link(i,x,0);            }        }        if (!dance()) puts("-1");    }    return 0;}