POJ 3740 Easy Finding (Exact cover problem)
Basic and obvious exact cover problem, using Dancing Links Algorithm (DLX).
DLX reference: Dancing Links.pdf
#include <stdio.h> const int MAXM = 20; const int MAXN = 400; int U[MAXM*MAXN], D[MAXM*MAXN], L[MAXM*MAXN], R[MAXM*MAXN], C[MAXM*MAXN], X[MAXM*MAXN]; int H[MAXM], S[MAXN], Q[MAXM]; int size, n, m; void init(int r, int c) { for(int i = 0; i <= c; ++i) { S[i] = 0; D[i] = U[i] = i; R[i] = i + 1; L[i+1] = i; } R[size = c] = 0; while(r) H[r--] = -1; } void remove(int c) { R[L[c]] = R[c], L[R[c]] = L[c]; for(int i = D[c]; i != c; i = D[i]) for(int j = R[i]; j != i; j = R[j]) U[D[j]] = U[j], D[U[j]] = D[j], --S[C[j]]; } void resume(int c) { R[L[c]] = L[R[c]] = c; for(int i = U[c]; i != c; i = U[i]) for(int j = L[i]; j != i; j = L[j]) ++S[C[U[D[j]] = D[U[j]] = j]]; } bool Dance(int k) { if(k > m) return false; int i, j, temp, c; if(!R[0]) { return true;; } for(temp = MAXN * MAXM, i = R[0]; i; i = R[i]) if(S[i] < temp) temp = S[c = i]; remove(c); for(i = D[c]; i != c; i = D[i]) { Q[k] = i; for(j = R[i]; j != i; j = R[j]) remove(C[j]); if(Dance(k+1)) return true; for(j = L[i]; j != i; j = L[j]) resume(C[j]); } resume(c); return false; } void Link(int r, int c) { ++size; C[size] = c; X[size] = r; ++S[c]; D[size] = D[c]; U[D[c]] = size; U[size] = c; D[c] = size; if(H[r] < 0) H[r] = L[size] = R[size] = size; else { R[size] = R[H[r]]; L[R[H[r]]] = size; L[size] = H[r]; R[H[r]] = size; } } int main() { while(scanf("%d%d", &m, &n) == 2) { if(!m && !n) break; init(m, n); for(int i = 1; i <= m; ++i) for(int j = 1; j <= n; ++j) { int c; scanf("%d", &c); if(c == 1) Link(i, j); } bool flag = true; for(int i = 1; i <= n; ++i) if(S[i] == 0) flag = false; if(flag && Dance(0)) printf("Yes, I found it\n"); else printf("It is impossible\n"); } return 0; }