题目链接:http://poj.org/problem?id=3740
dancing links 入门题
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <string> 5 #include <iomanip> 6 using namespace std; 7 int M, N; 8 #define maxn 16*300+5 9 int R[maxn], L[maxn], U[maxn], D[maxn]; 10 int H[maxn], C[maxn], ans[20], colsum[300+5]; 11 int mp[18][310]; 12 int cnt, head; 13 void addnode(int row, int col, int sum, int pre, int rowhead){ 14 cnt++; 15 H[cnt] = row; 16 C[cnt] = col; 17 18 if(pre == -1){ 19 R[cnt] = cnt; L[cnt] = cnt; 20 } 21 else if(sum == 2){ 22 R[pre] = cnt; R[cnt] = pre; 23 L[pre] = cnt; L[cnt] = pre; 24 } 25 else{ 26 R[cnt] = rowhead; R[pre] = cnt; 27 L[cnt] = pre; L[rowhead] = cnt; 28 } 29 30 D[U[col]] = cnt; 31 U[cnt] = U[col]; 32 D[cnt] = col; 33 U[col] = cnt; 34 35 colsum[col]++; 36 } 37 void init(){ 38 cnt = 0; head = 0; 39 memset(colsum, 0, sizeof(colsum)); 40 L[head] = N; R[head] = 1; D[head] = head; U[head] = head; 41 for(int i = 1; i <= N; i++){ 42 cnt++; 43 H[cnt] = 0; C[cnt] = i; 44 U[cnt] = cnt; D[cnt] = cnt; 45 if(i == N){ 46 R[cnt-1] = cnt; 47 L[cnt] = cnt-1; 48 R[cnt] = head; 49 } 50 else{ 51 R[cnt-1] = cnt; 52 L[cnt] = cnt-1; 53 } 54 } 55 int temp; 56 for(int i = 1; i <= M; i++){ 57 int sum = 0, pre = -1, rowhead; 58 for(int j = 1; j <= N; j++){ 59 scanf("%d", &temp); 60 if(temp == 1){ 61 sum++; 62 addnode(i, j, sum, pre, rowhead); 63 if(sum == 1) rowhead = cnt; 64 pre = cnt; 65 } 66 } 67 } 68 } 69 void remove(int c){ 70 R[L[c]] = R[c]; 71 L[R[c]] = L[c]; 72 for(int i = D[c]; i != c; i = D[i]){ 73 for(int j = R[i]; j != i; j = R[j]){ 74 U[D[j]] = U[j]; 75 D[U[j]] = D[j]; 76 colsum[C[j]]--; 77 } 78 } 79 } 80 void resume(int c){ 81 R[L[c]] = c; 82 L[R[c]] = c; 83 for(int i = U[c]; i != c; i = U[i]){ 84 for(int j = R[i]; j != i; j = R[j]){ 85 U[D[j]] = j; 86 D[U[j]] = j; 87 colsum[C[j]]++; 88 } 89 } 90 } 91 bool dance(int k){ 92 int c = R[head]; 93 if(c == head){ 94 return true; 95 } 96 int min = 999999; 97 for(int i = R[head]; i != head; i = R[i]){ 98 if(colsum[i] <= min){ 99 min = colsum[i]; 100 c = i; 101 } 102 } 103 remove(c); 104 for(int i = D[c]; i != c; i = D[i]){ 105 ans[k] = H[i]; 106 for(int j = R[i]; j != i; j = R[j]) remove(C[j]); 107 if(dance(k+1)) return true; 108 for(int j = L[i]; j != i; j = L[j]) resume(C[j]); 109 } 110 resume(c); 111 return false; 112 } 113 114 int main(){ 115 while(~scanf("%d%d", &M, &N)){ 116 init(); 117 if(dance(0)) printf("Yes, I found it "); 118 else printf("It is impossible "); 119 } 120 121 return 0; 122 }