您的位置:首页 > 其它

POJ 3740 Easy Finding (Exact cover problem)

2012-08-08 22:50 295 查看
Basic and obvious exact cover problem, using Dancing Links Algorithm (DLX).

DLX reference: Dancing Links.pdf


#include <stdio.h>

const int MAXM = 20;
const int MAXN = 400;

int U[MAXM*MAXN], D[MAXM*MAXN], L[MAXM*MAXN],
R[MAXM*MAXN], C[MAXM*MAXN], X[MAXM*MAXN];
int H[MAXM], S[MAXN], Q[MAXM];
int size, n, m;

void init(int r, int c)
{
for(int i = 0; i <= c; ++i)
{
S[i] = 0;
D[i] = U[i] = i;
R[i] = i + 1;
L[i+1] = i;
}
R[size = c] = 0;
while(r)	H[r--] = -1;
}

void remove(int c)
{
R[L[c]] = R[c], L[R[c]] = L[c];
for(int i = D[c]; i != c; i = D[i])
for(int j = R[i]; j != i; j = R[j])
U[D[j]] = U[j], D[U[j]] = D[j], --S[C[j]];
}

void resume(int c)
{
R[L[c]] = L[R[c]] = c;
for(int i = U[c]; i != c; i = U[i])
for(int j = L[i]; j != i; j = L[j])
++S[C[U[D[j]] = D[U[j]] = j]];
}

bool Dance(int k)
{
if(k > m)
return false;
int i, j, temp, c;
if(!R[0])
{
return true;;
}
for(temp = MAXN * MAXM, i = R[0]; i; i = R[i])
if(S[i] < temp)
temp = S[c = i];
remove(c);
for(i = D[c]; i != c; i = D[i])
{
Q[k] = i;
for(j = R[i]; j != i; j = R[j])
remove(C[j]);
if(Dance(k+1))
return true;
for(j = L[i]; j != i; j = L[j])
resume(C[j]);
}
resume(c);
return false;
}

void Link(int r, int c)
{
++size;
C[size] = c;
X[size] = r;
++S[c];

D[size] = D[c];
U[D[c]] = size;
U[size] = c;
D[c] = size;
if(H[r] < 0)
H[r] = L[size] = R[size] = size;
else
{
R[size] = R[H[r]];
L[R[H[r]]] = size;
L[size] = H[r];
R[H[r]] = size;
}
}

int main()
{
while(scanf("%d%d", &m, &n) == 2)
{
if(!m && !n)
break;
init(m, n);
for(int i = 1; i <= m; ++i)
for(int j = 1; j <= n; ++j)
{
int c;
scanf("%d", &c);
if(c == 1)
Link(i, j);
}
bool flag = true;
for(int i = 1; i <= n; ++i)
if(S[i] == 0)
flag = false;
if(flag && Dance(0))
printf("Yes, I found it\n");
else
printf("It is impossible\n");
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: