struct DLX{
int n,m,cnt,U[MAXN],D[MAXN],L[MAXN],R[MAXN],siz[MAXN],row[MAXN],col[MAXN],fir[MAXN];
bool vis[MAXM];
void clear(){
n=m=cnt=0;
memset(U,0,sizeof(U));memset(D,0,sizeof(U));memset(L,0,sizeof(U));memset(R,0,sizeof(U));
memset(siz,0,sizeof(siz));memset(row,0,sizeof(row));memset(col,0,sizeof(col));memset(fir,0,sizeof(fir));
}
void build(int x,int y){
n=x;m=y;cnt=m;
for(int i=1;i<=m;++i){L[i]=i-1;R[i]=i+1;U[i]=D[i]=i;}
R[m]=0;L[0]=m;R[0]=1;
}
void insert(int x,int y){
++cnt;
++siz[y];row[cnt]=x;col[cnt]=y;
U[cnt]=y;D[cnt]=D[y];U[D[y]]=cnt;D[y]=cnt;
if(!fir[x]){fir[x]=L[cnt]=R[cnt]=cnt;}
else{
L[cnt]=fir[x];R[cnt]=R[fir[x]];
L[R[fir[x]]]=cnt;R[fir[x]]=cnt;
}
}
void remove(int y){//只删除第y列
R[L[y]]=R[y];L[R[y]]=L[y];
for(int i=D[y];i!=y;i=D[i]){R[L[i]]=R[i];L[R[i]]=L[i];}
}
void recover(int y){
R[L[y]]=y;L[R[y]]=y;
for(int i=D[y];i!=y;i=D[i]){R[L[i]]=i;L[R[i]]=i;}
}
int h(){
memset(vis,false,sizeof(vis));
int res=0;
for(int i=R[0];i;i=R[i]){
if(vis[i]) continue;
vis[i]=true;
++res;
for(int j=D[i];j!=i;j=D[j])
for(int k=R[j];k!=j;k=R[k])
vis[col[k]]=true;
}
return res;
}
bool dance(int t,int maxdep){
if(t+h()-1>maxdep) return false;
if(!R[0]) return true;
int mini=0;
for(int i=R[0];i;i=R[i]) if(mini==0||siz[i]<siz[mini]) mini=i;
remove(mini);
for(int i=D[mini];i!=mini;i=D[i]){
for(int j=R[i];j!=i;j=R[j]){remove(col[j]);U[D[j]]=U[j];D[U[j]]=D[j];}//删除这一行和这一行所有1的列
if(dance(t+1,maxdep)) return true;
for(int j=R[i];j!=i;j=R[j]){recover(col[j]);U[D[j]]=D[U[j]]=j;}
}
recover(mini);
return false;
}
};
我理解的重复覆盖,应该是在删除的时候,只删掉枚举到的那一行,以及这一行里所有有1的列,但是我不理解为什么上面这份代码是错误的。而第一篇题解的代码似乎没有对枚举到的行进行删除,而是只删除了列,而且还没有删去列的头指针,为什么是对的。