您的位置:首页 > 其它

ZOJ 3209 Treasure Map

2012-08-31 17:55 302 查看
ZOJ_3209

精确覆盖问题,用Dancing Links直接求解即可。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 510
#define MAXM 910
#define MAXD 460010
#define INF 0x3f3f3f3f
int N, M, P, size, U[MAXD], D[MAXD], L[MAXD], R[MAXD], C[MAXD];
int S[MAXM], H[MAXN], ANS, vis[MAXM];
void prep(int n, int m)
{
int i;
for(i = 0; i <= m; i ++)
{
R[i] = i + 1, L[i + 1] = i;
U[i] = D[i] = i;
S[i] = 0;
}
R[m] = 0, size = m;
memset(H, -1, sizeof(H[0]) * (n + 1));
}
void insert(int r, int c)
{
++ size;
C[size] = c, ++ S[c];
D[size] = D[c], U[size] = c;
U[D[c]] = size, D[c] = size;
if(H[r] == -1) H[r] = L[size] = R[size] = size;
else
{
L[size] = H[r], R[size] = R[H[r]];
L[R[H[r]]] = size, R[H[r]] = size;
}
}
void init()
{
int i, j, k, x1, x2, y1, y2;
scanf("%d%d%d", &N, &M, &P);
prep(P, N * M);
for(k = 1; k <= P; k ++)
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
for(i = x1; i < x2; i ++)
for(j = y1; j < y2; j ++)
insert(k, i * M + j + 1);
}
}
void remove(int c)
{
int i, j;
R[L[c]] = R[c], L[R[c]] = L[c];
for(i = D[c]; i != c; i = D[i])
for(j = R[i]; j != i; j = R[j])
D[U[j]] = D[j], U[D[j]] = U[j], -- S[C[j]];
}
void resume(int c)
{
int i, j;
for(i = U[c]; i != c; i = U[i])
for(j = L[i]; j != i; j = L[j])
D[U[j]] = j, U[D[j]] = j, ++ S[C[j]];
R[L[c]] = c, L[R[c]] = c;
}
void dance(int dep)
{
if(R[0] == 0)
{
ANS = std::min(ANS, dep);
return ;
}
int i, j, t = INF, id;
for(i = R[0]; i != 0; i = R[i])
if(S[i] < t) t = S[i], id = i;
remove(id);
for(i = D[id]; i != id; i = D[i])
{
for(j = R[i]; j != i; j = R[j]) remove(C[j]);
dance(dep + 1);
for(j = L[i]; j != i; j = L[j]) resume(C[j]);
}
resume(id);
}
void solve()
{
ANS = INF;
dance(0);
printf("%d\n", ANS == INF ? -1 : ANS);
}
int main()
{
int t;
scanf("%d", &t);
while(t --)
{
init();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: