hust 1017 dancing links 精确覆盖模板题
2015-05-15 00:38
344 查看
最基础的dancing links的精确覆盖题目
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; #define N 1005 #define MAXN 1000100 struct DLX{ int n , m , size;//size表示当前dlx表中有多少个元素 int ans , k;//ans[]记录选取的行 int U[MAXN] , D[MAXN] , L[MAXN] , R[MAXN]; int row[MAXN] , col[MAXN] ; // 分别表示第 i 号节点属于第几行或者第几列 int cnt_col ;//分别表示第i行或者第i列有多少个节点 int first ; //行上的起始指针 void init(int _n , int _m) { n = _n , m = _m; size = m; for(int i=0 ; i<=m ; i++){ U[i] = D[i] = i; L[i] = i-1 , R[i] = i+1; } L[0] = m , R[m] = 0; for(int i=1 ; i<=n ; i++) first[i]=-1; for(int i=1 ; i<=m ; i++) cnt_col[i] = 0; // for(int i=0 ; i<=n ; i++) cout<<"here: "<<i<<" "<<L[i]<<" "<<R[i]<<endl; } void link(int r , int c) { ++size; //修改列上的情况 D[size] = D[c] , U[D[c]] = size; U[size] = c , D[c] = size; cnt_col[c]++ , col[size] = c ; //修改行上的情况 if(first[r]<0) first[r] = L[size] = R[size] = size; else{ R[size] = R[first[r]] , L[R[first[r]]] = size; L[size] = first[r] , R[first[r]] = size; } // cout<<" r: "<<r<<" c: "<<c<<" "<<size<<" "<<L[size]<<" "<<R[size]<<" "<<U[size]<<" "<<D[size]<<endl; row[size] = r; } void Remove(int c) { L[R[c]] = L[c] , R[L[c]] = R[c]; for(int i=D[c] ; i!=c ; i=D[i]){ for(int j=R[i] ; j!=i ; j=R[j]){ D[U[j]] = D[j] , U[D[j]] = U[j]; --cnt_col[col[j]]; } } } void Resume(int c) { for(int i=U[c] ; i!=c ; i=U[i]){ for(int j=L[i] ; j!=i ; j=L[j]){ U[D[j]] = D[U[j]] = j; ++cnt_col[col[j]]; } } R[L[c]] = L[R[c]] = c; } bool Dance(int d) { if(!R[0]){ k = d; return true; } int st = R[0]; //找到能删除最少节点的列先删除,这样递归的行的次数就会减少,提高效率 for(int i=st ; i!=0 ; i=R[i]){ if(cnt_col[st]>cnt_col[i]) st = i; } Remove(st); for(int i=D[st] ; i!=st ; i=D[i]){ ans[d] = row[i]; for(int j=R[i] ; j!=i ; j=R[j]) Remove(col[j]); if(Dance(d+1)) return true; for(int j=L[i] ; j!=i ; j=L[j]) Resume(col[j]); } Resume(st); return false; } }dlx; int main() { // freopen("a.in" , "r" , stdin); int n , m; while(~scanf("%d%d" , &n , &m)) { dlx.init(n , m); for(int r=1 ; r<=n ; r++){ int m , c; scanf("%d" , &m); for(int i=0 ; i<m ; i++){ scanf("%d" , &c); dlx.link(r , c); } } bool ok = dlx.Dance(0); if(ok){ printf("%d" , dlx.k); sort(dlx.ans , dlx.ans+dlx.k); for(int i=0 ; i<dlx.k ; i++) printf(" %d" , dlx.ans[i]); puts(""); } else puts("NO"); } return 0; }
相关文章推荐
- HUST1017 Exact cover —— Dancing Links 精确覆盖 模板题
- HUST 1017 Exact cover (精确覆盖|Dancing Links模板题)
- HUST_1017_ExactCover(DancingLinksX精确覆盖模板题)
- HUST 1017 Exact cover(Dancing Links)(精确覆盖问题)
- HUST1017 Exact cover —— Dancing Links 精确覆盖 模 4000 板题
- 【HUST】1017 Exact cover 精确覆盖入门题——Dancing Links
- [DLX 精确覆盖 模板题] HUST 1017 Exact cover
- 舞蹈链(Dancing Links) 解决精确覆盖问题 hustoj 1017 Exact cover zoj 3209 Treasure Map
- hust 1017 Exact cover 精确覆盖
- (简单) HUST 1017 Exact cover , DLX+精确覆盖。
- hust - 1017 - Exact cover(精确覆盖DLX)
- DLX模板 +解树独(Dancing Links X)精确覆盖问题
- HUST 1017 - Exact cover (Dancing Links 模板题)
- HUST 1017 Exact cover(DLX精确覆盖)
- hust 1017 Exact cover 精确覆盖 DLX 给定一个M*N的0-1矩阵,是否能选择一些行,使每一列只有一个’1’
- HUST 1017 - Exact cover (Dancing Links 模板题)
- HUST 1017 - Exact cover——舞蹈链,精确点覆盖
- hust 1017 dancing links 模板题
- HUST 1017 Exact cover(Dancing Links 精确覆盖)
- HUST 1017 Exact cover (Dancing Links 模板题)