DLX模板

对于数独问题

  1 const int N=16; //3*3数独
  2 const int MaxN=N*N*N+10;    // 一格能填9个数  9*9格
  3 const int MaxM=N*N*4+10;     // 9*9*4=(9+9+9)*9+9*9    (9+9+9)是9行 9列 9格 *9是9个数 9*9是81个格子
  4 const int maxnode=MaxN*4+MaxM+10;
  5 char g[MaxN];
  6 struct DLX
  7 {
  8     int n, m, size;
  9     int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode];
 10     int H[MaxN], S[MaxM];  // S: 各列节点数
 11     int ansd, ans[MaxN];
 12     void init(int _n, int _m)
 13     {
 14         n=_n;
 15         m=_m;
 16         for(int i=0; i<=m; i++)
 17         {
 18             S[i]=0;         //每一列元素个数
 19             U[i]=D[i]=i;//上下指针
 20             L[i]=i-1;      //
 21             R[i]=i+1;     //
 22         }
 23         R[m]=0;          //循环 最后一个指向第一个
 24         L[0]=m;           //第一个往前指向最后一个
 25         size=m;           // 节点总数
 26         for(int i=1; i<=n; i++)
 27             H[i]=-1;     //头指针
 28     }
 29     void Link(int r, int c)
 30     {
 31         S[Col[++size]=c]++;
 32         Row[size]=r;
 33         D[size]=D[c];
 34         U[D[c]]=size;
 35         U[size]=c;
 36         D[c]=size;
 37         if(H[r]<0)
 38             H[r]=L[size]=R[size]=size;
 39         else
 40         {
 41             R[size]=R[H[r]];
 42             L[R[H[r]]]=size;
 43             L[size]=H[r];
 44             R[H[r]]=size;
 45         }
 46     }
 47     void remove(int c)
 48     {
 49         L[R[c]]=L[c];
 50         R[L[c]]=R[c];
 51         for(int i=D[c]; i!=c; i=D[i])
 52             for(int j=R[i]; j!=i; j=R[j])
 53             {
 54                 U[D[j]]=U[j];
 55                 D[U[j]]=D[j];
 56                 S[Col[j]]--;
 57             }
 58     }
 59     void resume(int c)
 60     {
 61         for(int i=U[c]; i!=c; i=U[i])
 62             for(int j=L[i]; j!=i; j=L[j])
 63                 S[Col[U[D[j]]=D[U[j]]=j]]++;
 64         L[R[c]]=R[L[c]]=c;
 65     }
 66     bool Dance(int d)
 67     {
 68         if(R[0]==0)
 69         {
 70             for(int i=0;i<d;i++)
 71                 g[(ans[i]-1)/N]=(ans[i]-1)%N+'A';
 72             for(int i=0;i<N;i++)
 73             {
 74                 for(int j=0;j<N;j++)
 75                     printf("%c", g[i*N+j]);
 76                 printf("
");
 77             }
 78             printf("
");
 79             return true;
 80         }
 81         int c=R[0];
 82         for(int i=R[0]; i!=0; i=R[i])
 83             if(S[i]<S[c])
 84                 c=i;
 85         remove(c);
 86         for(int i=D[c]; i!=c; i=D[i])
 87         {
 88             ans[d]=Row[i];
 89             for(int j=R[i]; j!=i; j=R[j])
 90                 remove(Col[j]);
 91             if(Dance(d+1))
 92                 return true;
 93             for(int j=L[i]; j!=i; j=L[j])
 94                 resume(Col[j]);
 95         }
 96         resume(c);
 97         return false;
 98     }
 99 } dlx;
100 
101 void palce(int &r, int &c1, int &c2, int &c3, int &c4, int i, int j, int k)
102 {
103     r=(i*N+j)*N+k;  // 第几行
104     c1=i*N+j+1;     //  第几个格子
105     c2=N*N+i*N+k;   // 第i行上的k
106     c3=N*N*2+j*N+k; // 第j列上的k
107     c4=N*N*3+((i/4)*4+(j/4))*N+k; // 某宫中的k;
108 }
109 char s[20];
110 int main()
111 {
112     while(~scanf("%s", g))
113     {
114         for(int i=1;i<16;i++)
115         {
116             scanf("%s", s);
117             memcpy(g+16*i, s, 16);
118         }
119         dlx.init(N*N*N, 4*N*N);
120         for(int i=0; i<N; i++)
121             for(int j=0; j<N; j++)
122                 for(int k=1; k<=16; k++)
123                     if(g[i*N+j]=='-' || g[i*N+j]==k+'A'-1)
124                     {
125                         int r, c1, c2, c3, c4;
126                         palce(r, c1, c2, c3, c4, i, j, k);
127                         dlx.Link(r, c1);
128                         dlx.Link(r, c2);
129                         dlx.Link(r, c3);
130                         dlx.Link(r, c4);
131                     }
132         dlx.Dance(0);
133     }
134     return 0;
135 }
POJ 3076

( 以上的模板只能做唯一解的数独)

判读多解要做dfs

对于可重复覆盖

  1 #ifdef _WIN32
  2 #define LLD "%I64d"
  3 #else
  4 #define LLD "%lld"
  5 #endif
  6 #pragma comment(linker, "/STACK:1024000000,1024000000")
  7 //LL quick(LL a, LL b){LL ans=1;while(b){if(b & 1)ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans%mod;}
  8 inline int read(){char ch=' ';int ans=0;while(ch<'0' || ch>'9')ch=getchar();while(ch<='9' && ch>='0'){ans=ans*10+ch-'0';ch=getchar();}return ans;}
  9 inline void print(LL x){printf(LLD, x);puts("");}
 10 //inline void read(LL &ret){char c;int sgn;LL bit=0.1;if(c=getchar(),c==EOF) return ;while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();sgn=(c=='-')?-1:1;ret=(c=='-')?0:(c-'0');while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');if(c==' '||c=='
'){ ret*=sgn; return ; }while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;ret*=sgn;}
 11 
 12 const int maxnode=4000;
 13 const int MaxN=70;
 14 const int MaxM=70;
 15 int K;
 16 struct DLX
 17 {
 18     int n, m, size;
 19     int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode];
 20     int H[MaxN], S[MaxM];  // S: 各列节点数
 21     int ans[MaxN];
 22     void init(int _n, int _m)
 23     {
 24         n=_n;
 25         m=_m;
 26         for(int i=0; i<=m; i++)
 27         {
 28             S[i]=0;         //每一列元素个数
 29             U[i]=D[i]=i;//上下指针
 30             L[i]=i-1;      //
 31             R[i]=i+1;     //
 32         }
 33         R[m]=0;          //循环 最后一个指向第一个
 34         L[0]=m;           //第一个往前指向最后一个
 35         size=m;           // 节点总数
 36         for(int i=1; i<=n; i++)
 37             H[i]=-1;     //头指针
 38     }
 39     void Link(int r, int c)
 40     {
 41         S[Col[++size]=c]++;
 42         Row[size]=r;
 43         D[size]=D[c];
 44         U[D[c]]=size;
 45         U[size]=c;
 46         D[c]=size;
 47         if(H[r]<0)
 48             H[r]=L[size]=R[size]=size;
 49         else
 50         {
 51             R[size]=R[H[r]];
 52             L[R[H[r]]]=size;
 53             L[size]=H[r];
 54             R[H[r]]=size;
 55         }
 56     }
 57     void remove(int c)
 58     {
 59         for(int i=D[c]; i!=c; i=D[i])
 60             L[R[i]]=L[i], R[L[i]]=R[i];
 61     }
 62     void resume(int c)
 63     {
 64         for(int i=U[c]; i!=c; i=U[i])
 65             L[R[i]]=R[L[i]]=i;
 66     }
 67     bool v[maxnode];
 68     int f()
 69     {
 70         int ret=0;
 71         for(int c=R[0];c!=0;c=R[c])
 72             v[c]=1;
 73         for(int c=R[0];c!=0;c=R[c])
 74             if(v[c])
 75             {
 76                 ret++;
 77                 v[c]=0;
 78                 for(int i=D[c];i!=c;i=D[i])
 79                     for(int j=R[i];j!=i;j=R[j])
 80                         v[Col[j]]=0;
 81             }
 82         return ret;
 83     }
 84     bool Dance(int d)
 85     {
 86         if(d+f()>K)
 87             return false;
 88         if(R[0]==0)
 89             return d<=K;
 90         int c=R[0];
 91         for(int i=R[0]; i!=0; i=R[i])
 92             if(S[i]<S[c])
 93                 c=i;
 94         for(int i=D[c]; i!=c; i=D[i])
 95         {
 96             remove(i);
 97             for(int j=R[i]; j!=i; j=R[j])
 98                 remove(j);
 99             if(Dance(d+1))
100                 return true;
101             for(int j=L[i]; j!=i; j=L[j])
102                 resume(j);
103             resume(i);
104         }
105         return false;
106     }
107 } dlx;
108 struct node
109 {
110     int x, y;
111 }city[MaxM];
112 LL dis(node a, node b)
113 {
114     return (LL)abs(a.x-b.x)+(LL)abs(a.y-b.y);
115 }
116 int main()
117 {
118     int t, ca=1;
119     t=read();
120     while(t--)
121     {
122         int n=read();
123         K=read();
124         for(int i=0;i<n;i++)
125             scanf("%d%d", &city[i].x, &city[i].y);
126         LL l=0, r=100000000000LL, ans=0;
127         while(l<=r)
128         {
129             LL mid=(l+r)>>1;
130             dlx.init(n, n);
131             for(int i=0;i<n;i++)
132                 for(int j=0;j<n;j++)
133                     if(dis(city[i], city[j])<=mid)
134                         dlx.Link(i+1, j+1);
135             if(dlx.Dance(0))
136             {
137                 r=mid-1;
138                 ans=mid;
139             }
140             else
141                 l=mid+1;
142         }
143         printf("Case #%d: ", ca++);
144         print(ans);
145     }
146     return 0;
147 }
HDUOJ 5046

两篇资料:

http://wenku.baidu.com/view/b3f6fa868762caaedd33d47a.html

http://wenku.baidu.com/view/4ab7bd00a6c30c2259019eae.html?from=rec&pos=0&weight=31&lastweight=5&count=5

原文地址:https://www.cnblogs.com/Empress/p/4261653.html