ZOJ 3209 Dancing Links
Idea: This question is quite good. Originally, the template was not customized by myself. After understanding the Dancing Links, I found a template, and then I got a better understanding of this question, you also know how to create a matrix in practice.
Regard the matrix of n * m as n * m lattice, and act as n * m columns, just like the single number. Each rectangle has a row.
After the columns are created, you can use the dance chain to solve the problem.
The problem is to select the least part from these rows so that each column is overwritten and only once.
# Pragma comment (linker, "/STACK: 1024000000,1024000000") # include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define mem (a, B) memset (a, B, sizeof (a) # define lson I <1, l, mid # define rson I <1 | 1, mid + 1, r # define llson j <1, l, mid # define rrson j <1 | 1, mid + 1, r # define INF 0x7fffffff # define maxn 1000005 typedef long ll; typedef unsigned long ull; using namespace std; int head, sz; int U [maxn], D [maxn], L [maxn], R [maxn]; // int H [maxn], ROW [maxn], C [maxn], S [maxn], O [maxn]; void remove (int c) {L [R [c] = L [c]; R [L [c] = R [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) {for (int I = U [c]; I! = C; I = U [I]) {for (int j = L [I]; j! = I; j = L [j]) {++ S [C [j]; U [D [j] = j; D [U [j] = j ;}l [R [c] = c; R [L [c] = c ;} void init (int m) // m is the column {head = 0; // the header pointer is 0 for (int I = 0; I <= m; I ++) {U [I] = I; D [I] = I; // create a bidirectional cross linked list L [I] = I-1; R [I] = I + 1; S [I] = 0 ;} R [m] = 0; L [0] = m; S [0] = INF + 1; sz = m + 1; memset (H, 0, sizeof (H);} void insert (int I, int j) {if (H [I]) {L [sz] = L [H [I]; R [sz] = H [I]; L [R [sz] = sz; R [L [sz] = sz;} else {L [sz] = sz; R [sz] = sz; H [I] = sz;} U [sz] = U [j]; D [sz] = j; U [D [sz] = sz; D [U [sz] = sz; C [sz] = j; ROW [sz] = I; ++ S [j]; ++ sz;} int ans; void dfs (int k) {if (R [head] = head) {if (ans> k) ans = k; return;} int s = INF, c; for (int t = R [head]; t! = Head; t = R [t]) if (S [t]
> T; while (t --) {int n, m, p, I, j, k, x1, y1, x2, y2; scanf ("% d", & n, & m, & p); init (n * m); for (I = 1; I <= p; I ++) {scanf ("% d", & x1, & y1, & x2, & y2); for (j = x1; j