zju 3209 精确覆盖问题
行为方块 列为小方格
省赛的时候也不会 看都没看
#include <iostream>
using namespace std;
const int MAXN = 510;
const int MAXM = 910;
const int MAXC = MAXN+MAXM+MAXN*MAXM;
int U[MAXC], D[MAXC], L[MAXC], R[MAXC];
int ROW[MAXC], COL[MAXC];
int hashRow[MAXN], hashCol[MAXM];
int lenCol[MAXM];
int head, ans, eid, cn;
void init()
{
memset(ROW, -1, sizeof(ROW));
memset(COL, -1, sizeof(COL));
memset(hashRow, -1, sizeof(hashRow));
memset(hashCol, -1, sizeof(hashCol));
head = 0, eid = 1, cn = 0;
U[head] = D[head] = L[head] = R[head] = head;
}
void insRow(int r)
{
U[D[head]] = eid;
U[eid] = head;
D[eid] = D[head];
D[head] = eid;
L[eid] = R[eid] = eid;
hashRow[r] = eid++;
}
void insCol(int c)
{
L[R[head]] = eid;
L[eid] = head;
R[eid] = R[head];
R[head] = eid;
U[eid] = D[eid] = eid;
lenCol[c] = 1;
hashCol[c] = eid++;
}
void insElement(int r, int c)
{
int rid = hashRow[r], cid = hashCol[c];
L[R[rid]] = eid;
L[eid] = rid;
R[eid] = R[rid];
R[rid] = eid;
U[D[cid]] = eid;
U[eid] = cid;
D[eid] = D[cid];
D[cid] = eid;
ROW[eid] = r, COL[eid++] = c;
lenCol[c]++;
}
void insert(int r, int c)
{
if (hashRow[r] == -1)
{
insRow(r);
}
if (hashCol[c] == -1)
{
cn++;
insCol(c);
}
insElement(r, c);
}
void RemoveCol(int cid)
{
L[R[cid]] = L[cid];
R[L[cid]] = R[cid];
int i, j;
for (i = D[cid]; i != cid; i = D[i])
{
for (j = R[i]; j != i; j = R[j])
{
if (COL[j] != -1)
{
U[D[j]] = U[j];
D[U[j]] = D[j];
--lenCol[COL[j]];
}
}
}
}
void ResumeCol(int cid)
{
int i, j;
for (i = U[cid]; i != cid; i = U[i])
{
for (j = L[i]; j != i; j = L[j])
{
if (COL[j] != -1)
{
U[D[j]] = j;
D[U[j]] = j;
++lenCol[COL[j]];
}
}
}
L[R[cid]] = cid;
R[L[cid]] = cid;
}
void dfs(int k)
{
if (k >= ans)
{
return;
}
if (R[head] == head)
{
ans = k;
return;
}
int MIN = INT_MAX, c;
int i, j;
for (i = R[head]; i != head; i = R[i])
{
if (COL[D[i]] == -1)
{
c = i;
continue;
}
if (lenCol[COL[D[i]]] < MIN)
{
MIN = lenCol[COL[D[i]]];
c = i;
}
}
RemoveCol(c);
for (i = D[c]; i != c; i = D[i])
{
for (j = R[i]; j != i; j = R[j])
{
if (COL[j] != -1)
{
RemoveCol(hashCol[COL[j]]);
}
}
dfs(k+1);
for (j = L[i]; j != i; j = L[j])
{
if (COL[j] != -1)
{
ResumeCol(hashCol[COL[j]]);
}
}
}
ResumeCol(c);
}
void solution()
{
init();
int n, m, p;
int x1, x2, y1, y2;
scanf("%d %d %d", &n, &m, &p);
int i, j, k;
ans = p + 1;
for (i = 0; i < p; ++i)
{
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
for (j = y1; j < y2; ++j)
{
for (k = x1; k < x2; ++k)
{
insert(i, k+j*n);
}
}
}
if (cn != n*m)
{
goto end;
}
dfs(0);
end: printf("%d\n", ans > p ? -1 : ans);
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
solution();
}
return 0;
}