(模板)dlx 精确覆盖和重复覆盖

来源:互联网 发布:淘宝童装能做吗 编辑:程序博客网 时间:2024/05/17 08:30

精确覆盖

#define mxn 1120#define N 1000200int n, m, t, size;int U[N], D[N], L[N], R[N], C[N], Row[N];int H[mxn], S[mxn];void init(int n, int m) {for(int i = 0; i <= m; ++i) {S[i] = 0, D[i] = U[i] = i;L[i+1] = i, R[i] = i + 1;}R[m] = 0, size = m;for(int i = 1; i <= n; ++i)H[i] = -1;}void link(int r, int c) {++S[C[++size] = c];Row[size] = r;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[size]] = size;L[size] = H[r];R[H[r]] = size;}}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])U[D[j]] = D[U[j]] = j, ++S[C[j]];}int ans[mxn], cnt;bool dance(int k) {int i, j, tmp, c;if( !R[0] ) return 1;for(tmp = mxn, i = R[0]; i; i = R[i])if(S[i] < tmp) tmp = S[c = i];remove(c);for(i = D[c]; i != c; i = D[i]) {ans[cnt++] = Row[i]; //用栈记录解for(j = R[i]; j != i; j = R[j]) remove(C[j]);if(dance(k + 1)) return 1;--cnt;for(j = L[i]; j != i; j = L[j]) resume(C[j]);}resume(c);return 0;}

重复覆盖

const int mxm = 15 * 15 + 10;const int mxn = 15 * 15 + 10;const int mxnode = mxn * mxm;const int inf = 0x3f3f3f3f;//能不加的行尽量不加, 减少搜索时间int sz;int U[mxnode], D[mxnode], R[mxnode], L[mxnode], Row[mxnode],  Col[mxnode];int H[mxn], S[mxm];int ansd;void init(int n, int m) {int i;for(i = 0; i <= m; ++i) {S[i] = 0, U[i] = D[i] = i;L[i] = i - 1, R[i] = i + 1;}R[m] = 0, L[0] = m, sz = m;for(i = 1; i <= n; ++i) H[i] = -1;}void link(int r, int c) {++S[Col[++sz] = c];Row[sz] = r; D[sz] = D[c]; U[D[c]] = sz; U[sz] = c; D[c] = sz;if(H[r] < 0) H[r] = L[sz] = R[sz] = sz;else {R[sz] = R[H[r]]; L[R[H[r]]] = sz; L[sz] = H[r]; R[H[r]] = sz;}}void remove(int c) {for(int i = D[c]; i != c; i = D[i])L[R[i]] = L[i], R[L[i]] = R[i];}void resume(int c) {for(int i = U[c]; i != c; i = U[i])L[R[i]] = R[L[i]] = i;}bool vv[mxm];int f() {int ret = 0, c, i, j;for(c = R[0]; c != 0; c = R[c]) vv[c] = 1;for(c = R[0]; c != 0; c = R[c])if(vv[c]) {++ret, vv[c] = 0;for(i = D[c]; i != c; i = D[i])for(j = R[i]; j != i; j = R[j])vv[Col[j]] = 0;}return ret;}void dance(int d) {if(d + f() >= ansd) return;if(R[0] == 0) {if(d < ansd) ansd = d;return;}int c = R[0], i, j;for(i = R[0]; i; i = R[i])if(S[i] < S[c]) c = i;for(i = D[c]; i != c; i = D[i]) {remove(i);for(j = R[i]; j != i; j = R[j]) remove(j);dance(d + 1);for(j = L[i]; j != i; j = L[j]) resume(j);resume(i);}}


0 0
原创粉丝点击