题目链接:http://acm.hust.edu.cn/problem/show/1017
上个星期在空闲时间看了一下DLX博客http://www.cnblogs.com/grenet/p/3145800.html
然后今天昨天学习了bin巨的DLX模板,关于模板的个人理解代码已标出,下面开始做几道DLX==
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 struct DLX{ 6 int n,m,size,ansd,ans[1005]; 7 int U[100005],D[100005],L[100005],R[100005]; 8 int Row[100005],Col[100005],H[1005],S[1005]; 9 //H表示该行最右点,S表示该列点数 10 //head在原点,在坐标轴第二象限的DLX 11 void init(int _n,int _m){ 12 n=_n; m=_m; 13 for (int i=0;i<=m;i++){ 14 S[i]=0; 15 U[i]=D[i]=i; 16 L[i]=i-1; R[i]=i+1; 17 } 18 R[m]=0; L[0]=m; 19 size=m; 20 for (int i=1;i<=n;i++) H[i]=-1; 21 } 22 void link(int r,int c){ 23 S[c]++; 24 Col[++size]=c; Row[size]=r; 25 D[size]=D[c]; U[D[c]]=size; 26 U[size]=c; D[c]=size; 27 if (H[r]<0) H[r]=L[size]=R[size]=size; 28 else{ 29 R[size]=R[H[r]]; 30 L[R[H[r]]]=size; 31 L[size]=H[r]; 32 R[H[r]]=size; 33 } 34 } 35 void remove(int c){ 36 L[R[c]]=L[c]; R[L[c]]=R[c]; 37 for (int i=D[c];i!=c;i=D[i]) 38 for (int j=R[i];j!=i;j=R[j]){ 39 U[D[j]]=U[j]; 40 D[U[j]]=D[j]; 41 S[Col[j]]--; 42 } 43 } 44 void resume(int c){ 45 for (int i=U[c];i!=c;i=U[i]) 46 for (int j=L[i];j!=i;j=L[j]){ 47 U[D[j]]=D[U[j]]=j; 48 S[Col[j]]++; 49 } 50 L[R[c]]=R[L[c]]=c; 51 } 52 int dance(int d){ 53 if (R[0]==0){ 54 ansd=d; 55 return 1; 56 } 57 int c=R[0]; 58 for (int i=R[0];i;i=R[i]) 59 if (S[i]<S[c]) c=i; 60 remove(c); 61 for (int i=D[c];i!=c;i=D[i]){ 62 ans[d]=Row[i]; 63 for (int j=R[i];j!=i;j=R[j]) remove(Col[j]); 64 if (dance(d+1)) return 1; 65 for (int j=L[i];j!=i;j=L[j]) resume(Col[j]); 66 } 67 resume(c); 68 return 0; 69 } 70 }; 71 DLX g; 72 int main() 73 { 74 int n,m,x,y; 75 while (~scanf("%d%d",&n,&m)){ 76 g.init(n,m); 77 for (int i=1;i<=n;i++){ 78 scanf("%d",&x); 79 while (x--){ 80 scanf("%d",&y); 81 g.link(i,y); 82 } 83 } 84 if (!g.dance(0)) printf("NO\n"); 85 else{ 86 printf("%d ",g.ansd); 87 for (int i=0;i<g.ansd;i++) 88 printf(" %d",g.ans[i]); 89 printf("\n"); 90 } 91 } 92 return 0; 93 }