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...