您的位置:首页 > 其它

精确覆盖DLX算法模板

2016-08-07 20:08 302 查看
代码

struct DLX
{
int n,id;
int L[maxn],R[maxn],U[maxn],D[maxn];
int C[maxn],S[maxn],loc[maxn][2];
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
=0;
id=n;
memset(S,0,sizeof(S));
}
void AddRow(int x,int col,int A[]) //传入参数是行标号,列长,列数组
{
bool has=false;
int first=id+1;
for(int y=1;y<=col;y++)
{
if(A[y]==0) continue;
has=true;
++id;
L[id]=id-1; R[id]=id+1;
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(!has) return;
R[id]=first; L[first]=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;


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: