您的位置:首页 > 其它

精确覆盖DLX算法模板另一种写法

2016-08-07 20:47 423 查看
代码

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
=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;


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