zoukankan      html  css  js  c++  java
  • ZOJ 3209 Treasure Map dancing links

    分析:dancing links 裸题 ,只要把每个格子看成一列就好了,精确不重复覆盖问题

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const int N=500005;
    const LL mod=1e9+7;
    int n,m,sz;
    int u[N],l[N],r[N],d[N];
    int col[N],row[N];
    int h[505],s[905];
    void init()
    {
        for(int i=0; i<=m; ++i)
        {
            s[i]=0;
            u[i]=d[i]=i;
            l[i]=i-1;
            r[i]=i+1;
        }
        r[m]=0;
        l[0]=m;
        sz=m;
        for(int i=1; i<=n; ++i)
            h[i]=-1;
    }
    void link(int x,int y)
    {
        ++sz;
        ++s[y],col[sz]=y,row[sz]=x;
        u[sz]=u[y],d[u[y]]=sz;
        d[sz]=y,u[y]=sz;
        if(h[x]==-1)h[x]=l[sz]=r[sz]=sz;
        {
            l[sz]=l[h[x]];
            r[l[h[x]]]=sz;
            r[sz]=h[x];
            l[h[x]]=sz;
        }
    }
    void del(int y)
    {
        l[r[y]]=l[y];
        r[l[y]]=r[y];
        for(int i=d[y]; i!=y; i=d[i])
        {
            for(int j=r[i]; j!=i; j=r[j])
            {
                u[d[j]]=u[j];
                d[u[j]]=d[j];
                --s[col[j]];
            }
        }
    }
    void resume(int y)
    {
        for(int i=u[y]; i!=y; i=u[i])
        {
            for(int j=l[i]; j!=i; j=l[j])
            {
                d[u[j]]=u[d[j]]=j;
                ++s[col[j]];
            }
        }
        r[l[y]]=l[r[y]]=y;
    }
    int ans;
    void dance(int pos)
    {
        if(pos>=ans)return;
        if(!r[0])
        {
            if(pos<ans)ans=pos;
            return;
        }
        int t=r[0];
        for(int i=r[0]; i!=0; i=r[i])
            if(s[i]<s[t])t=i;
        del(t);
        for(int i=d[t]; i!=t; i=d[i])
        {
            for(int j=r[i]; j!=i; j=r[j])
                del(col[j]);
            dance(pos+1);
            for(int j=l[i]; j!=i; j=l[j])
                resume(col[j]);
        }
        resume(t);
    }
    int main()
    {
        int T,n1,m1,p;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&n1,&m1,&p);
            n=p;
            m=n1*m1;
            init();
            int x1,x2,y1,y2;
            for(int i=1; i<=p; ++i)
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                for(int j=x1+1; j<=x2; ++j)
                    for(int k=y1+1; k<=y2; ++k)
                        link(i,(k-1)*n1+j);
            }
            ans=505;
            dance(0);
            if(ans==505)printf("-1
    ");
            else printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    10003 Cutting Sticks(区间dp)
    Cocos2d-x init() 和 onEnter() 区别
    HDU1181【有向图的传递闭包】
    空间参考系统与WKT解析
    面试经典-分金条
    uvalive 3971
    lua学习:使用Lua处理游戏数据
    面试经典--两个房间 每间房间三盏灯
    浙江大学PAT上机题解析之2-11. 两个有序链表序列的合并
    顺序队列之C++实现
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5286659.html
Copyright © 2011-2022 走看看