对于数独问题
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("\n"); 77 } 78 printf("\n"); 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 }
( 以上的模板只能做唯一解的数独)
判读多解要做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=='\n'){ 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 }
两篇资料:
http://wenku.baidu.com/view/b3f6fa868762caaedd33d47a.html
http://wenku.baidu.com/view/4ab7bd00a6c30c2259019eae.html?from=rec&pos=0&weight=31&lastweight=5&count=5