struct DLX { int n , m,size; int U[N],D[N],R[N],L[N],row[N],col[N]; int ans[N],S[N]; int ansd; void init(int a,int b) { n = a; m = b; for(int i=0; i<=m; i++) { S[i] = 0; U[i] = D[i] = i; L[i] = i-1; R[i] = i+1; } R[m] = 0; L[0] = m; size = m; for(int i=1; i<=n; i++) ans[i] = -1; } void addRow(int r,int c) { ++S[col[++size]=c]; row[size] = r; D[size] = D[c]; U[D[c]] = size; U[size] = c; D[c] = size ; if(ans[r]<0) ans[r] = L[size] = R[size] = size; else { R[size] = R[ans[r]]; L[R[ans[r]]] = size; L[size] = ans[r]; R[ans[r]] = size; } } void remove (int c) { for(int i= D[c]; i!=c; i=D[i]) { L[R[i]] = L[i]; R[L[i]] = R[i]; } } void resume(int c) { for(int i = U[c]; i!=c; i=U[i]) { L[R[i]]=R[L[i]] = i; } } bool v[N]; int f() { //精确覆盖区估算剪枝 int ret = 0; for(int c =R[0]; c!=0; c=R[c]) v[c] = true; for(int c = R[0]; c!=0; c=R[c]) { if(v[c]) { ret++; v[c] = false; for(int i=D[c]; i!=c; i=D[i]) { for(int j=R[i]; j!=i; j=R[j]) { v[col[j]]=false; } } } } return ret; } void dance(int d) { if(d+f()>=ansd) return ; if(R[0]==0) { if(ansd>d) ansd = d; return; } int c = R[0]; for(int i=R[0]; i!=0; i=R[i]) { if(S[i]<S[c]) { c=i; } } for(int i=D[c]; i!=c; i=D[i]) { remove(i); for(int j=R[i]; j!=i; j=R[j]) remove(j); dance(d+1); for(int j=L[i]; j!=i; j=L[j]) resume(j); resume(i); } } } g;
版权声明:都是兄弟,请随意转载,请注明兄弟是谁
时间: 2024-10-16 15:39:48