POJ 3740 精確覆蓋問題,DLX模版

2022-03-10 07:48:00 字數 2441 閱讀 8243

花3小時打上的注釋,分享給大家。。

1 #include 2 #include 3

const

int maxr = 20;4

const

int maxc = 310;5

const

int maxn = maxr * maxc +maxc;

6const

int inf = maxr * 10;7

8int

n, m;

9int

l[maxn], r[maxn], u[maxn], d[maxn];

10int

c[maxn], o[maxn], s[maxn], h[maxr];

11int

nodenumber;

1213

void

init()

1425 l[0] =m;

26 r[m] = 0

;27 nodenumber = m + 1

;28 memset(h, 0, sizeof

(h));29}

3031

void insert(int i, int

j)32

40else

4146

47 u[nodenumber] = u[j]; //

節點的上指標指向上面乙個節點

48 d[nodenumber] = j; //

節點的下指標指向對應的列表頭

49 u[d[nodenumber]] = nodenumber; //

更新列表頭的上指標指向當前節點

50 d[u[nodenumber]] = nodenumber; //

更新上乙個節點的下指標指向當前節點

5152 c[nodenumber] = j; //

記錄列號

53 o[nodenumber] = i; //

記錄行號

5455 ++ s[j]; //

s當中記錄著每列節點的個數

56 ++ nodenumber; //

新建乙個節點 57}

5859

void remove(int

c)6071}

72}7374

void resume(int

c)7584}

85 r[l[c]] = c; //

最後恢復列

86 l[r[c]] =c;87}

8889

bool dfs(int

k)90

95//

因為要輸出最優秀(最少的行)的答案,每次都要優先搜尋列節點最少的列

96int count =inf, c;

97for(int i=r[0];i;i=r[i]) //

從第乙個列開始,直到右指標指向列頭,即逐列遍歷

98107

}108

}109 remove(c); //

把該列和列上符合要求的行刪除

110for(int i=d[c];i!=c;i=d[i]) //

在被刪除的列上,往下遍歷

111116

if(dfs(k+1)) //

遞迴層數+1,深度搜尋

117120

for(int j=l[i];j!=i;j=l[j]) //

從該行最後乙個節點往左遍歷,第乙個節點不遍歷

121124

}125 resume(c); //

遞迴跳出,恢復之前刪除的列

126return

false

;127

}128

129int

main()

130

146*/

147for(int i=1;i<=n;++i)

148156

}157

}158

bool flag = true

;159

for(int i=1;i<=m;++i)

160166

}167

if(flag && dfs(0)) //

進入深度搜尋

168171

else

172175

}176

return0;

177}

178/*

1796 7

1800 0 1 0 1 1 0

1811 0 0 1 0 0 1

1820 1 1 0 0 1 0

1831 0 0 1 0 0 0

1840 1 0 0 0 0 1

1850 0 0 1 1 0 1

186*/

poj 3740 DLX(精確覆蓋)

題意 經典的精確覆蓋問題。思路 精確覆蓋問題是npc的,用dlx能夠比較有效的搜尋。寫完兩個數獨再寫這個就不難了 實際上這個是原始問題,數獨只是dlx的應用 include include define n 16 define m 300 struct nodep n m m 5 int s n 5...

POJ 2676 鍛鍊碼力 數獨,精確覆蓋的DLX

題意 先給定資料組數t,每組資料都是乙個數獨遊戲,輸出它任意乙個解。自從學了dlx之後,還沒寫過精確覆蓋,只用自己yy 寫過一次可重複覆蓋。這次寫乙個精確覆蓋。數獨麻煩的就是構建m矩陣,想了有一段時間。對於構建數獨的m矩陣,大都是這樣的套路 行表示的是在某個位置填某個數。列表示的是 某個位置是否有數...

poj 3074 poj 3076(精確覆蓋)

兩個題都是數獨,題意很明確。建圖的思路大神寫的很好 行 一共9 9 9 729行。一共9 9小格,每一格有9種可能性 1 9 每一種可能都對應著一行。列 一共 9 9 9 9 81 324 種前面三個9分別代表著9行9列和9小 塊。乘以9的意思是9種可能,因為每種可能只可以選擇乙個。81代表著81個...