DLX 模板
1. 精确覆盖
int U[N],R[N],D[N],L[N],num[N],H[N],col[N],line[N]; int head,id,flag; int nn,mm; void prepare() { id=mm; for(int i=0;i<=mm;i++) { num[i]=0; U[i]=i; D[i]=i; R[i]=i+1; L[i+1]=i; } R[mm]=0; L[0]=mm; memset(H,-1,sizeof(H)); } void link(int tn,int tm) { id++; num[ line[id]=tm ]++; col[id]=tn; U[ D[tm] ]=id; D[id]=D[tm]; U[id]=tm; D[tm]=id; if(H[tn]<0) H[tn]=R[id]=L[id]=id; else { L[ R[H[tn]] ]=id; R[id] = R[ H[tn] ]; L[id]=H[tn]; R[ H[tn] ]=id; } } void remove(int s) { L[R[s]]=L[s]; R[L[s]]=R[s]; for(int i=D[s];i!=s;i=D[i]) { for(int j=R[i];j!=i;j=R[j]) { U[D[j]]=U[j]; D[U[j]]=D[j]; num[ line[j] ]--; } } } void resume(int s) { L[R[s]]=R[L[s]]=s; for(int i=U[s];i!=s;i=U[i]) for(int j=L[i];j!=i;j=L[j]) { U[D[j]]=D[U[j]]=j; num[line[j]]++; } } int h() { int ff=0; for(int i=R[head];i!=head;i=R[i]) { if(D[i]==i) { ff=1; break; } } if(ff==1) return 0; else return 1; } void dfs(int s) { if(flag==1) return ; if(R[head]==head) { flag=1; // return ; } if( h()==0 ) return ; int tmi=INF,tu; for(int i=R[head];i!=head;i=R[i]) if(num[i]<tmi) { tmi=num[i]; tu=i; } remove(tu); for(int i=D[tu];i!=tu;i=D[i]) { for(int j=R[i];j!=i;j=R[j]) remove(line[j]); path[s]=col[i]; dfs(s+1); for(int j=L[i];j!=i;j=L[j]) resume( line[j] ); } resume(tu); }
2. 重复覆盖
#define INF 0x3fffffff int U[N],D[N],R[N],L[N],num[N],H[N],col[N],line[N]; int head,id,mi; int nn,mm; // 矩阵的行和列 void prepare() { for(int i=0;i<=mm;i++) { num[i]=0; U[i]=i; D[i]=i; R[i]=i+1; L[i+1]=i; } R[mm]=0; L[0]=mm; memset(H,-1,sizeof(H)); } void link(int tn,int tm) { id++; num[line[id]=tm]++; col[id]=tn; U[D[tm]]=id; D[id]=D[tm]; U[id]=tm; D[tm]=id; if( H[tn]<0 ) H[tn]=R[id]=L[id]=id; else { L[R[H[tn]]]=id; R[id]=R[H[tn]]; L[id]=H[tn]; R[H[tn]]=id; } } int h() { int mark[66]; memset(mark,0,sizeof(mark)); int sum=0; for(int i=R[head];i!=head;i=R[i]) { if(mark[i]==0) { sum++; mark[i]=1; for(int j=D[i];j!=i;j=D[j]) for(int k=R[j];k!=j;k=R[k]) mark[ line[k] ]=1; } } return sum; } void remove(int s) { for(int i=D[s];i!=s;i=D[i]) { R[L[i]]=R[i]; L[R[i]]=L[i]; } } void resume(int s) { for(int i=U[s];i!=s;i=U[i]) R[L[i]]=L[R[i]]=i; } void dfs(int s) { if(s+h()>=mi) return ; if(R[head]==head) { mi=s; return ; } int tmi=INF,tu; for(int i=R[head];i!=head;i=R[i]) { if(num[i]<tmi) { tmi=num[i]; tu=i; } } for(int i=D[tu];i!=tu;i=D[i]) { remove(i); for(int j=R[i];j!=i;j=R[j]) remove(j); dfs(s+1); for(int j=L[i];j!=i;j=L[j]) resume(j); resume(i); } }