• ZOJ 3209 Treasure Map


    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;    
    }
  • 相关阅读:
    共识算法之争(PBFT,Raft,PoW,PoS,DPoS,Ripple)
    区块链:共识算法POW
    区块链目前的几大共识算法
    StringUtils.isEmpty和StringUtils.isBlank用法
    StringUtils.isEmpty和StringUtils.isBlank用法
    hyper-v 无线网连接
    hyper-v 无线网连接
    hyper-v 无线网连接
    hyper-v 无线网连接
    nat和静态映射
  • 原文地址:https://www.cnblogs.com/staginner/p/2665800.html
Copyright © 2020-2023  润新知