HDOJ2828-DLX, 重复覆盖小变形

代码是昨天写的,今天又试着做重复覆盖的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;
}


你可能感兴趣的:(c,IM)