dancing link

dancing link x

DLX又称dancing links X 是一种 解决重复覆盖和精确覆盖的高效算法

精准覆盖:一个全集S有若干个子集S1,S2,……Sn,选取其中若干个子集,使得这些集合中出现了S中每个元素各一次。举个例子:

全集S={1,2,3,4,5,6,7}, 用子集S1={1,2,3},S2={3,4,5,7},S3={4,5,6,7},S4={1,5,6,7},S5={4,5}精确覆盖,结果显然是选取S1和S3。

刚才的例子表示为:

\[\left|\begin{array}{cccc} S & 1 &2 &3 &4 &5 &6&7\\ S_1&1&1&1&0&0&0&0\\ S_2&0&0&1&1&1&0&1\\ S_3&0&0&0&1&1&1&1\\ S_4&1&0&0&0&1&1&1\\ S_5&0&0&0&1&1&0&0\\ \end{array}\right| \\ \]

\[核心操作:选取一个集合(一行),把~该行~和~该行上有点的列和包含这些列的行删除\\ 比如我们删掉了第一行\\ \left|\begin{array}{cccc} S&4&5&6&7\\ S_3&1&1&1&1\\ S_5&1&1&0&0 \end{array}\right| \\ \]

接下来如果我们选择了S3,显然矩阵为空,我们找到了一组解,但若我们选择了S5则矩阵变为

\[\left|\begin{array}{cccc} S&6&7 \end{array}\right| \\ \]

矩阵未覆盖完但已经无集合可用,覆盖失败,于是要回溯,于是矩阵又为

\[\left|\begin{array}{cccc} S&4&5&6&7\\ S_3&1&1&1&1\\ S_5&1&1&0&0 \end{array}\right| \\ \]

int n,m,cnt;//矩阵的长,宽,点的数量
	int l[mx],r[mx],u[mx],d[mx],row[mx],col[mx];//每个点的左,右,上下,行,列信息
	int h[mx];//每行的头结点
	int s[mx];//每列的结点数
	int ans,ansk[mx];//需要ans个子集,分别为ansk[]

没码完一会继续咕咕咕

posted @ 2020-07-17 08:36  INFP  阅读(178)  评论(0编辑  收藏  举报