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;
}

posted on 2009-11-22 16:41  ZAFU_VA  阅读(516)  评论(0编辑  收藏  举报

导航