DLX演算法模板(注釋詳解)

2021-10-04 09:41:53 字數 2762 閱讀 3314

解決這類問題的大體思路:

1)判斷所有的情況數,作為列

2)判斷所有的條件數,作為行

3)判斷每一行滿足哪些條件,可以插入1

4)判斷是精確覆蓋還是重複覆蓋

5)注意輸入輸出

精確覆蓋

struct dlx

///第0個結點(表頭head)左指標指向node1,右指標指向nodem

///第m個結點右指標指向head,使得行首結點首尾相接

l[0]

=m,r[0]

=1; r[m]=0

; siz=m;

clclow

(h);

///列首結點初始化為-1,表明該行全為0,沒有指向哪個為1的結點

clc(ans)

; ansed=0;

///答案的數量為0

}void

link

(int r,

int c)

else

return;}

void

del(

int c)

///刪除列及對應的行

return;}

void

recover

(int c)

///恢復列及對應的行

r[l[c]

]=c;

///恢復列首結點

l[r[c]

]=c;

return;}

bool

dancing

(int dep)

///開始跳舞

int c=r[0]

;///表頭右指標指向的列首結點c

del(c)

;///刪除第c列,及該列的1所在的行

for(

int i=d[c]

;i!=c;i=d[i]

)return

false;}

}dlx;

模板題:

exact cover(hust 1017)

重複覆蓋

其實是準確覆蓋的轉化模型。

首先選擇當前要覆蓋的列,將該列刪除,列舉覆蓋到該列的所有行:對於某一行r,假設認為它是解集中的乙個,那麼該行所能覆蓋到的列都不必再搜,所以刪除該行覆蓋到的所有列。注意此時不用刪去覆蓋到這些列的其它行,因為一列中允許有多個1。

h()函式剪枝利用的思想是a*搜尋中的估價函式。即,對於當前的遞迴深度k下的矩陣,估計其最好情況下(即最少還需要多少步)才能出解。也就是,如果將能夠覆蓋當前列的所有行全部選中,去掉這些行能夠覆蓋到的列,將這個操作作為一層深度。重複此操作直到所有列全部出解的深度是多少。如果當前深度加上這個估價函式返回值,其和已然不能更優(也就是已經超過當前最優解),則直接返回,不必再搜。

**與精確覆蓋的區別:

1)刪除/恢復函式不同:精確覆蓋是刪除/恢復行及對應的列,重複覆蓋是刪除/恢復列

2)精確覆蓋由於是np問題,所以使用a*優化

3)dancing函式有區別,見**

#include

#include

#include

#define clc(x) memset(x,0,sizeof(x))

#define clclow(x) memset(x,-1,sizeof(x))

using

namespace std;

const

int maxn=15*

15+5,maxnode=maxn*maxn,inf=

1000000000

;struct dlx

///第0個結點(表頭head)左指標指向node1,右指標指向nodem

///第m個結點右指標指向head,使得行首結點首尾相接

l[0]

=m,r[0]

=1; r[m]=0

; siz=m;

clclow

(h);

///列首結點初始化為-1,表明該行全為0,沒有指向哪個為1的結點

clc(ans)

; ansed=inf;

///次數初始化為inf

}void

link

(int r,

int c)

else

return;}

void

remove

(int c)

///刪除第i列

return;}

void

resume

(int c)

///恢復列

return;}

inth()

///ida*的h函式,獲得代價

return ans;

}void

dancing

(int dep)

///開始跳舞

int c=r[0]

;///表頭右指標指向的列首結點c

for(

int i=r[0]

;i!=

0;i=r[i])if

(s[i]

) c=i;

//del(c);///精確覆蓋

for(

int i=d[c]

;i!=c;i=d[i]

)//recover(c);///精確覆蓋

return;}

}dlx;

DLX演算法合集 I

dlx是一種相當神奇的資料結構,通常用於解決矩陣 多為稀疏矩陣 的 重複 精確 覆蓋的問題。不過一般這類問題的難點是抽出轉化關係,剩下的幾乎就是套模板 include include include include include include includeusing namespace std...

P4929 模板 舞蹈鏈 DLX

n m 的矩形有 0 1 要求選出若干行使得每一列有且僅有乙個 1 精確覆蓋問題指的是乙個集合 s 和它的若干個子集集合 t 要求選出 t 的乙個子集使得裡面的集合元素剛好覆蓋集合 s dlx 全稱是 dancing link x 其中 dancing link 是指交叉十字迴圈雙向鏈,x 是指暴搜...

IDEA 方法注釋模板和類注釋模板

1.類注釋模板 在編輯區域輸入你想要注釋的內容,點選應用,再點選儲存,在你建立新的類時就可以自動生成了 2.方法注釋模板 開啟 file setting editor livetemplates 點選右邊上面那個綠色的 號,選擇template group雙擊,然後彈出乙個視窗,起名,然後點選ok ...