1、精确覆盖。
View Code
1 #include<cstdio> 2 #define INF 0x7FFFFFFF 3 #define MAXN 1000010 4 int n, m, size; 5 int L[MAXN], R[MAXN], U[MAXN], D[MAXN], H[MAXN]; 6 int S[MAXN], C[MAXN], X[MAXN], Q[MAXN]; 7 void Init() 8 { 9 int i; 10 for (i = 0; i <= m; i++) 11 { 12 S[i] = 0; 13 L[i + 1] = i; 14 R[i] = i + 1; 15 U[i] = D[i] = i; 16 } 17 R[m] = 0; 18 size = m + 1; 19 } 20 void Remove(int c) 21 { 22 int i, j; 23 R[L[c]] = R[c]; 24 L[R[c]] = L[c]; 25 for (i = D[c]; i != c; i = D[i]) 26 { 27 for (j = R[i]; j != i; j = R[j]) 28 { 29 D[U[j]] = D[j]; 30 U[D[j]] = U[j]; 31 S[C[j]]--; 32 } 33 } 34 } 35 void Resume(int c) 36 { 37 int i, j; 38 R[L[c]] = c; 39 L[R[c]] = c; 40 for (i = D[c]; i != c; i = D[i]) 41 { 42 for (j = R[i]; j != i; j = R[j]) 43 { 44 U[D[j]] = j; 45 D[U[j]] = j; 46 S[C[j]]++; 47 } 48 } 49 } 50 void Link(int r, int c) 51 { 52 D[size] = D[c]; 53 U[size] = c; 54 U[D[c]] = size; 55 D[c] = size; 56 if (H[r] < 0) 57 H[r] = L[size] = R[size] = size; 58 else 59 { 60 L[size] = H[r]; 61 R[size] = R[H[r]]; 62 L[R[H[r]]] = size; 63 R[H[r]] = size; 64 } 65 S[c]++; 66 C[size] = c; 67 X[size++] = r; 68 } 69 bool Dance(int now) 70 { 71 int i, j, c, temp; 72 if (R[0] == 0) 73 return true; 74 for (temp = INF, i = R[0]; i; i = R[i]) 75 { 76 if (S[i] < temp) 77 { 78 c = i; 79 temp = S[i]; 80 } 81 } 82 Remove(c); 83 for (i = D[c]; i != c; i = D[i]) 84 { 85 for (j = R[i]; j != i; j = R[j]) 86 Remove(C[j]); 87 if (Dance(now + 1)) 88 return true; 89 for (j = L[i]; j != i; j = L[j]) 90 Resume(C[j]); 91 } 92 Resume(c); 93 return false; 94 }
2、重复覆盖。
View Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define MAXN 110 5 #define MAXM 1000000 6 #define INF 0x7FFFFFFF 7 using namespace std; 8 int G[MAXN][MAXN]; 9 int L[MAXM], R[MAXM], U[MAXM], D[MAXM]; 10 int size, ans, S[MAXM], H[MAXM], C[MAXM]; 11 bool vis[MAXN * 100]; 12 void Link(int r, int c) 13 { 14 U[size] = c; 15 D[size] = D[c]; 16 U[D[c]] = size; 17 D[c] = size; 18 if (H[r] < 0) 19 H[r] = L[size] = R[size] = size; 20 else 21 { 22 L[size] = H[r]; 23 R[size] = R[H[r]]; 24 L[R[H[r]]] = size; 25 R[H[r]] = size; 26 } 27 S[c]++; 28 C[size++] = c; 29 } 30 void Remove(int c) 31 { 32 int i; 33 for (i = D[c]; i != c; i = D[i]) 34 { 35 L[R[i]] = L[i]; 36 R[L[i]] = R[i]; 37 } 38 } 39 void Resume(int c) 40 { 41 int i; 42 for (i = D[c]; i != c; i = D[i]) 43 L[R[i]] = R[L[i]] = i; 44 } 45 int A() 46 { 47 int i, j, k, res; 48 memset(vis, false, sizeof(vis)); 49 for (res = 0, i = R[0]; i; i = R[i]) 50 { 51 if (!vis[i]) 52 { 53 res++; 54 for (j = D[i]; j != i; j = D[j]) 55 { 56 for (k = R[j]; k != j; k = R[k]) 57 vis[C[k]] = true; 58 } 59 } 60 } 61 return res; 62 } 63 void Dance(int now) 64 { 65 if (R[0] == 0) 66 ans = min(ans, now); 67 else if (now + A() < ans) 68 { 69 int i, j, temp, c; 70 for (temp = INF,i = R[0]; i; i = R[i]) 71 { 72 if (temp > S[i]) 73 { 74 temp = S[i]; 75 c = i; 76 } 77 } 78 for (i = D[c]; i != c; i = D[i]) 79 { 80 Remove(i); 81 for (j = R[i]; j != i; j = R[j]) 82 Remove(j); 83 Dance(now + 1); 84 for (j = L[i]; j != i; j = L[j]) 85 Resume(j); 86 Resume(i); 87 } 88 } 89 } 90 void Init(int m) 91 { 92 int i; 93 for (i = 0; i <= m; i++) 94 { 95 R[i] = i + 1; 96 L[i + 1] = i; 97 U[i] = D[i] = i; 98 S[i] = 0; 99 } 100 R[m] = 0; 101 size = m + 1; 102 }
3、精确覆盖与重复覆盖的区别:
精确覆盖:给定一个01矩阵,现在要选择一些行,使得每一列有且仅有一个1。
每次选定一个元素个数最少的列,从该列中选择一行加入答案,删除该行所有的列以及与该行冲突的行。
重复覆盖:给定一个01矩阵,现在要选择一些行,使得每一列至少有一个1。
每次选定一个元素个数最少的列,从该列中选择一行加入答案,删除该行所有的列。与该行冲突的行可能满足重复覆盖。
4、精确覆盖:
【SPOJ】1771 Yet Another N-Queen Problem
5、重复覆盖:
【HDU】3529 Bomberman - Just Search!