SPOJ 1771 DLX精確覆蓋,重複覆蓋

2022-05-11 19:55:54 字數 2457 閱讀 5089

dlx的題,做過這題才算是會吧。

這道題轉化成了精確覆蓋模型來做,一開始,只是單純的要覆蓋完行列和斜線,wa。

後來醒悟了,不能這樣,只要覆蓋全部行或列即可。雖然如此,但某些細節地方很關鍵不能考慮到。

特別要注意的是

for(int i=r[c];i;i=r[i])

找最小值只能是在ne之前,為什麼呢?因為我們要完全覆蓋行。可行嗎?可行。稍微留意一下dlx的模板就知道,它其實在選中一列之後,是會列舉列上的行值,

也就是說,該列(代表棋盤某一行)的每乙個們置都會考慮到,不必擔心無解。

dlx這個演算法很巧妙啊,其實它只是一種高效的剪枝吧。妙妙妙,做過這題後才算真正懂得這個演算法。

#include#include #include #include #include using namespace std;

const int maxn=500;

const int maxnode=500*2500;

int ne;

int anst[maxn];

struct dlx

r[n] = 0 ;

l[0] = n;

sz = n + 1 ;

memset(s,0,sizeof(s));

} void addrow(int r,vectorc1)

r[sz - 1] = first ; l[first] = sz - 1;

} // 順著鍊錶a,遍歷除s外的其他元素

#define for(i,a,s) for(int i = a[s]; i != s ; i = a[i])

void remove(int c)

} void restore(int c)

l[r[c]] = c;

r[l[c]] = c;

} bool dfs(int d)

remove(c);

for(i,d,c)

restore(c);

return false;

} void solve()

};dlx solver;

int puzzle[100][100];

int main()

} solver.init(6*ne-2);

vectorcolumns;

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

}} solver.solve();

} return 0;

}

摘重複覆蓋模板

const int maxn=360000;

const int maxc=500;

const int maxr=500;

const int inf=0x3f3f3f3f;

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

int s[maxc], h[maxr], size;

///不需要s域

void link(int r, int c)

size++;

}void remove(int c)

void resume(int c)

int h()

return ret;

}int ans;

void dance(int k)

r[n] = 0 ;

l[0] = n;

sz = n + 1 ;

memset(s,0,sizeof(s));

} void addrow(int r,vectorc1)

r[sz - 1] = first ; l[first] = sz - 1;

} // 順著鍊錶a,遍歷除s外的其他元素

#define for(i,a,s) for(int i = a[s]; i != s ; i = a[i])

void remove(int c)

} void restore(int c)

l[r[c]] = c;

r[l[c]] = c;

} bool dfs(int d)

// 找s最小的列c

int c = r[0] ;

for(i,r,0) if(s[i] < s[c]) c = i;

remove(c);

for(i,d,c)

restore(c);

return false;

} bool solve(vector& v)

};dlx solver;

int main()

solver.addrow(i,c1);

}vectorans;

bool flag ;

flag = solver.solve(ans);

if(flag )

else printf("no\n");

} return 0;

}

DLX 精確覆蓋 重複覆蓋

給定乙個n m的矩陣,有些位置為1,有些位置為0。如果g i j 1則說明i行可以覆蓋j列。problem 1 選定最少的行,使得每列有且僅有乙個1.2 選定最少的行,使得每列至少乙個1.這類屬於np問題的問題,可以使用搜尋解決。但是普通的搜尋必超時無疑。因此我們要設法加優化來加快速度。dancin...

DLX 精確覆蓋問題

精確覆蓋問題 給定乙個由0 1組成的矩陣,問是否能找到乙個行的集合,使得集合中每一列都恰好包含乙個1 如圖 演算法x 通過dfs,每次選取一行可行 模擬演算法x過程 很容易想到上面的搜尋,但是狀態的改變很難操作,包括了刪除和復原,使用普通的資料結構運算根本停不下來。於是,一位大師想到了神奇的資料結構...

poj 3740 DLX(精確覆蓋)

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