Hust 1017 exact cover
The example in the knuth paper is a bare question that is precisely covered.
# Include <cstdio> # include <cstring>/** find a row set in the 01 matrix, to precisely overwrite all columns, the so-called exact overwrite means that there is only one and only one column in all rows, and repeated overwrite allows multiple columns. **/Const int maxn = 100000 + 123; const int maxc = 1000 + 5; int s [maxc], L [maxn], R [maxn], d [maxn], U [maxn]; int H [maxc], OK [maxc], SZ, C [maxn], Mark [maxn]; // H is the horizontal header, it is not necessary to know void Link (INT row, int col) {s [col] ++; C [SZ] = Col; // The CDomain points to the column header U [SZ] = U [col]; d [U [col] = SZ; d [SZ] = Col; U [col] = SZ; If (H [row] =-1) h [row] = L [SZ] = R [SZ] = SZ; else {L [SZ] = L [H [row]; R [L [H [row] = SZ; R [SZ] = H [row]; L [H [row] = SZ;} mark [SZ] = row; // mark Which line is each vertex (which line of the question must be output) SZ ++;} void remove (INT col) {L [R [col] = L [col]; R [L [col] = R [col]; // Delete Col for (INT I = d [col]; I in the column object linked list! = Col; I = d [I]) {// Delete the row with 1 element in the col column for (Int J = R [I]; J! = I; j = R [J]) {// Delete the 1 element of each row and modify the S domain U [d [J] = U [J] of the column. d [U [J] = d [J]; s [C [J] -- ;}} void resume (INT col) {for (INT I = U [col]; I! = Col; I = U [I]) {for (Int J = L [I]; J! = I; j = L [J]) {u [d [J] = J; d [U [J] = J; s [C [J] ++;} // restore the deleted element and restore the S domain} // restore the deleted row L [R [col] = Col; R [L [col] = Col;} bool Dance (int K) {// printf ("% d \ n", k ); if (R [0] = 0) {printf ("% d", k); For (INT I = 0; I <K; ++ I) printf ("% d", OK [I]); puts (""); Return true;} int c = R [0]; for (INT I = R [0]; I; I = R [I]) if (s [I] <s [c]) C = I; remove (C ); // printf ("Remove Col % d \ n", c); For (INT I = d [c]; I! = C; I = d [I]) {OK [k] = mark [I]; for (Int J = R [I]; J! = I; j = R [J]) Remove (C [J]); If (Dance (k + 1) return true; For (Int J = L [I]; j! = I; j = L [J]) Resume (C [J]);} resume (c); Return false;} void initl (INT X) {for (INT I = 0; I <= x; ++ I) // I <X ??? {S [I] = 0; d [I] = U [I] = I; L [I + 1] = I; R [I] = I + 1 ;} /// initialize the R [x] = 0; SZ = x + 1; // The real elements start from m + 1 memset (H,-1, sizeof (h); // mark name of each position} int main () {int n, m; while (~ Scanf ("% d", & N, & M) {initl (m); For (INT I = 1; I <= N; ++ I) {int K; scanf ("% d", & K); While (k --) {int X; scanf ("% d", & X); Link (I, x) ;}} if (! Dance (0) puts ("no");} return 0 ;}