代码
struct DLX { int n,id; int L[maxn],R[maxn],U[maxn],D[maxn]; int C[maxn],S[maxn],loc[maxn][2]; int H[ms]; void init(int nn=0) //传列长 { n=nn; for(int i=0;i<=n;i++) U[i]=D[i]=i,L[i]=i-1,R[i]=i+1; L[0]=n; R[n]=0; id=n; memset(S,0,sizeof(S)); memset(H,-1,sizeof(H)); } void Link(int x,int y) { ++id; D[id]=y; U[id]=U[y]; D[U[y]]=id; U[y]=id; loc[id][0]=x,loc[id][1]=y; C[id]=y; S[y]++; if(H[x]==-1) H[x]=L[id]=R[id]=id; else { int a=H[x]; int b=R[a]; L[id]=a; R[a]=id; R[id]=b; L[b]=id; H[x]=id; } } void Remove(int Size) { for(int j=D[Size];j!=Size;j=D[j])//将左右两边连接 L[R[j]]=L[j],R[L[j]]=R[j]; } void Resume(int Size) { for(int j=U[Size];j!=Size;j=U[j])//恢复 L[R[j]]=R[L[j]]=j; } bool vis[ms];//标记行是否访问过 int h() //启发式函数 { int ret=0; int i,j,k; memset(vis,0,sizeof(vis)); for(i=R[0];i;i=R[i]) { if(vis[i]) continue; ret++; for(j=D[i];j!=i;j=D[j]) //所有关联的标记了 for(k=R[j];k!=j;k=R[k]) vis[C[k]]=1; } return ret; } void dfs(int step) { if(step+h()>=ans) return; if(R[0]==0){ ans=min(ans,step); return; } int Min=INF,c=-1; for(int i=R[0];i;i=R[i]) if(Min>S[i]){ Min=S[i]; 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); dfs(step+1); for(int j=L[i];j!=i;j=L[j]) Resume(j); Resume(i); } return; } }dlx;
时间: 2024-10-06 22:17:29