# DLX算法介绍

X算法是一种常规的回溯算法，我们可以用一个递归过程求精确覆盖问题。

if A is empty, the problem is solved; terminate successfully.

Otherwise choose a column, c.

Choose a row r, such that A[r,c] = 1.

Include r in the partial solution.

For each j such that A[r, j] = 1,

delete column j from matrix A;

for each i such A[i,j] = 1,

delete row i from matrix A.

Repeat this algorithm recursively on the reduced matrix A.

L[R[x]] = L[x];

R[L[x]] = R[x];

L[R[x]] = x;

R[L[x]] = x;

DLX的算法用递归过程用search(k)描述如下，k初始化为0

if R[h] = h, print the current solution and return.

Otherwise choose a column object c

Cover column c

For each r = D[c], D[D[c]],...., while r <> c

set Ok = r

for each j = R[r], R[R[r]],..., while j <> r

cover column j

search(k + 1)

for each j = L[r], L[L[r]],..., while j <> r

uncover column j

uncover column c

c = R[h]

s = 无穷大

for each j = R[h], R[R[h]],..., while j <> h

if S[j] < s then s = s[j], c = j

L[R[c]] = L[c], R[L[c]] = R[c]

for i = D[c], D[D[c]], ..., while i <> c

for j = R[i], R[R[i]],..., while j <> i

U[D[j]] = U[j]    D[U[j]] = D[j]  S[C[j]]--

for i = U[c], U[U[c]],...,while i <> c

for j = L[i], L[L[i]], ..., while j != i

U[D[j]] = j  D[U[j]] = j   S[C[j]]++

L[R[c]] = c           R[L[c]] = c

DLX的模板代码如下：

class DLX
{
private :
int n;
int L[MAXN], R[MAXN], U[MAXN], D[MAXN];
int col[MAXN], row[MAXN], S[MAXN];
int ans[MAXN], ansd;
int sz;

public:
void init(int n)
{
this->n = n;

for (int i = 0; i <= n; i++) {
L[i] = i - 1;
R[i] = i + 1;
U[i] = i;
D[i] = i;
}
L[0] = n;
R[n] = 0;
sz = n + 1;

memset(S, 0x00, sizeof(S));
}

{
int first = sz;
size_t size = columns.size();
for (size_t i = 0; i < size; i++) {
int c = columns[i];
L[sz] = sz - 1;
R[sz] = sz + 1;
U[sz] = U[c];
D[U[c]] = sz;
D[sz] = c;
U[c] = sz;
row[sz] = r;
col[sz] = c;
S[c]++;
sz++;
}

L[first] = sz - 1;
R[sz - 1] = first;
}

bool solve(vector<int> &v)
{
if (!dfs(0)) return false;

v.clear();
for (int i = 0; i < ansd; i++) {
v.push_back(ans[i]);
}

return true;
}

#define FOR(i, A, s) for (int i = A[s]; i != s; i = A[i])

void cover(int c)
{
L[R[c]] = L[c];
R[L[c]] = R[c];

FOR (i, D, c) {
FOR (j, R, i) {
S[col[j]]--;
D[U[j]] = D[j];
U[D[j]] = U[j];
}
}
}

void uncover(int c)
{
FOR (i, U, c) {
FOR (j, L, i) {
S[col[j]]++;
D[U[j]] = j;
U[D[j]] = j;
}
}

R[L[c]] = c;
L[R[c]] = c;
}

bool dfs(int dep)
{
if (R[0] == 0) {
ansd = dep;
return true;
}

int c = R[0];
FOR (i, S, 0) {
if (S[i] < S[c]) c = i;
}

cover(c);
FOR (i, D, c) {
ans[dep] = row[i];
FOR (j, R, i) {
cover(col[j]);
}

if (dfs(dep + 1)) return true;

FOR (j, L, i) {
uncover(col[j]);
}
}

uncover(c);
return false;
}
};


03-09 3799

11-04 6485
09-05 52
05-12 887
04-16 1741
03-15 884
06-10 1319
07-12 631
05-16
02-15 2116
12-23 335
10-25 3701
07-23 1057
01-06 5637