很裸的Dancing Links。。
题目链接:http://acm.hust.edu.cn:8080/judge/problem/viewProblem.action?id=10702
题目:给你一个0-1矩阵,问你能否精确覆盖,如果可以输出任意一组解,否则输出NO;
code:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /*Problem: HUST 1017 User: zyzamp
2 Memory: 1924 KB Time: 268 MS
3 Language: C++ Result: Accepted */
4 # include<stdio.h>
5 # include<string.h>
6 # include<time.h>
7 # define N 1005
8 # define V 102005
9 int U[V],D[V];
10 int L[V],R[V];
11 int C[V];
12 int H[N],S[N],mark[V];
13 int size,n,m,OK[N],flag;
14 void Link(int r,int c)
15 {
16 S[c]++;C[size]=c;
17 U[size]=U[c];D[U[c]]=size;
18 D[size]=c;U[c]=size;
19 if(H[r]==-1) H[r]=L[size]=R[size]=size;
20 else
21 {
22 L[size]=L[H[r]];R[L[H[r]]]=size;
23 R[size]=H[r];L[H[r]]=size;
24 }
25 mark[size]=r;
26 size++;
27 }
28 void remove(int c)//删除列
29 {
30 int i,j;
31 L[R[c]]=L[c];
32 R[L[c]]=R[c];
33 for(i=D[c];i!=c;i=D[i])
34 {
35 for(j=R[i];j!=i;j=R[j])
36 {
37 U[D[j]]=U[j],D[U[j]]=D[j];
38 S[C[j]]--;
39 }
40 }
41 }
42 void resume(int c)
43 {
44 int i,j;
45 for(i=U[c];i!=c;i=U[i])
46 {
47 for(j=L[i];j!=i;j=L[j])
48 {
49 U[D[j]]=j;D[U[j]]=j;
50 S[C[j]]++;
51 }
52 }
53 L[R[c]]=c;
54 R[L[c]]=c;
55 }
56 void Dance(int k)
57 {
58 int i,j,Min,c;
59 if(!R[0])
60 {
61 flag=1;
62 printf("%d",k);
63 for(i=0;i<k;i++)
64 printf(" %d",mark[OK[i]]);
65 printf("\n");
66 return;
67 }
68 for(Min=N,i=R[0];i;i=R[i])
69 if(S[i]<Min) Min=S[i],c=i;
70 remove(c);//删除该列
71 for(i=D[c];i!=c;i=D[i])
72 {
73 OK[k]=i;
74 //remove(i);
75 for(j=R[i];j!=i;j=R[j])
76 remove(C[j]);
77 Dance(k+1);
78 if(flag) return;
79 for(j=L[i];j!=i;j=L[j])
80 resume(C[j]);
81 //resume(i);
82 }
83 resume(c);
84 }
85 int main()
86 {
87 int i,j,num;
88 while(scanf("%d%d",&n,&m)!=EOF)
89 {
90 for(i=0;i<=m;i++)
91 {
92 S[i]=0;
93 D[i]=U[i]=i;
94 L[i+1]=i;R[i]=i+1;
95 }R[m]=0;
96 size=m+1;
97 memset(H,-1,sizeof(H));
98 memset(mark,0,sizeof(mark));
99 for(i=1;i<=n;i++)
100 {
101 scanf("%d",&num);
102 while(num--)
103 {
104 scanf("%d",&j);
105 Link(i,j);
106 }
107 }
108 flag=0;
109 Dance(0);
110 if(!flag) printf("NO\n");
111 }
112 return 0;
113 }