POJ 3740 Easy Finding

题目链接: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 }
原文地址:https://www.cnblogs.com/titicia/p/4452040.html