hihoCoder 1317 搜索四·跳舞链(DLX算法)

 

题目链接:http://hihocoder.com/problemset/problem/1317

       就是一个DLX的模板,判断能否选出几行来覆盖整个矩阵...


AC代码:

#include 
using namespace std;
const int maxn = 110;
const int maxm = 110;
const int maxnode = 110 * 110;
int L[maxnode], R[maxnode], U[maxnode], D[maxnode];
int C[maxnode],H[maxn],cnt[maxm],vis[maxn],ans[maxn],Row[maxnode];
int n,m,id,len;

void init(){
    for(int i=0;i<=m;i++){
        cnt[i] = 0; U[i] = D[i] = i;
        L[i + 1] = i; R[i] = i + 1;
    }
    R[m] = 0; id = m + 1;
    memset(H, -1, sizeof(H));
}

void Link(int r, int c){
    cnt[c]++; C[id] = c; Row[id] = r;
    U[id] = U[c]; D[ U[c] ] = id;
    D[id] = c; U[c] = id; Row[id] = r;
    if(H[r] == -1) H[r] = L[id] = R[id] = id;
    else{
        L[id] = L[ H[r] ]; R[ L[ H[r] ] ] = id;
        R[id] = H[r]; L[ H[ r ] ] = id;
    }
    id++;
}

void Remove(int Size){
    L[ R[Size] ] = L[Size];
    R[ L[Size] ] = R[Size];
    for(int i=D[Size];i!=Size;i=D[i]){
        for(int j=R[i];j!=i;j=R[j]){
            U[ D[j] ] = U[j]; D[ U[j] ] = D[j];
            cnt[ C[j] ]--;
        }
    }
}

void Resume(int Size){
    for(int i=D[Size];i!=Size;i=D[i]){
        for(int j=R[i];j!=i;j=R[j]){
            U[ D[j] ] = j; D[ U[j] ] = j;
            cnt[ C[j] ]++;
        }
    }
    L[ R[Size] ] = Size;R[ L[Size] ] = Size;
}

bool DLX(int k){
    int pos,mm = maxn;
    if(R[0] == 0){
        len = k;
        return true;
    }
    for(int i=R[0];i;i=R[i]){
        if(mm > cnt[i]){
            mm = cnt[i];
						pos = i;
        }
    }
    Remove(pos);
    for(int i=D[pos];i!=pos;i=D[i]){
        ans[k] = Row[i];
        for(int j=R[i];j!=i;j=R[j]) Remove(C[j]);
        if(DLX(k + 1)) return true;
        for(int j=L[i];j!=i;j=L[j]) Resume(C[j]);
    }
    Resume(pos);
    return false;
}

int main(){
    int u,v,a,T;
		scanf("%d",&T);
    while(T--){
			scanf("%d%d",&n,&m);
        init();
        for(int i=1;i<=n;i++){
          for(int j=1;j<=m;j++){
						int xx;
						scanf("%d",&xx);
						if(xx) Link(i, j);
					}
        }
        bool ans = DLX(0);
        if(ans == false) printf("No\n");
        else puts("Yes");
    }
    return 0;
}

 

你可能感兴趣的:(ACM_覆盖问题)