码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ 3209 Dancing Links

时间:2014-08-29 21:25:42      阅读:285      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   os   io   ar   for   2014   问题   

思路:这题挺好的,本来模板不是自己敲的嘛,理解了Dancing Links后是找了一个模板的,然后正好这题让自己加深理解了,也知道在实际中怎么建矩阵求解了。

把n*m的矩阵看成n*m个格子,像那个数独一样,作为n*m列;每一个矩形一行。

行列都建好矩阵后,就可以用舞蹈链求解了。

问题即转化为从这些行中选择最少的一部分使每一列被覆盖且仅覆盖一次。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<bitset>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define llson j<<1,l,mid
#define rrson j<<1|1,mid+1,r
#define INF 0x7fffffff
#define maxn 1000005
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int head,sz;
int U[maxn],D[maxn],L[maxn],R[maxn];//上下左右链表指针
int H[maxn],ROW[maxn],C[maxn],S[maxn],O[maxn];
void remove(int c)
{
    L[R[c]]=L[c];
    R[L[c]]=R[c];
    for(int i=D[c]; i!=c; i=D[i])
        for(int j=R[i]; j!=i; j=R[j])
        {
            U[D[j]]=U[j];
            D[U[j]]=D[j];
            --S[C[j]];
        }
}
void resume(int c)
{
    for(int i=U[c]; i!=c; i=U[i])
    {
        for(int j=L[i]; j!=i; j=L[j])
        {
            ++S[C[j]];
            U[D[j]]=j;
            D[U[j]]=j;
        }
    }
    L[R[c]]=c;
    R[L[c]]=c;
}
void init(int m)//m是列
{
    head=0;//头指针为0
    for(int i=0; i<=m; i++)
    {
        U[i]=i;
        D[i]=i;//建立双向十字链表
        L[i]=i-1;
        R[i]=i+1;
        S[i]=0;
    }
    R[m]=0;
    L[0]=m;
    S[0]=INF+1;
    sz=m+1;
    memset(H,0,sizeof(H));
}
void insert(int i, int j)
{
    if(H[i])
    {
        L[sz] = L[H[i]];
        R[sz] = H[i];
        L[R[sz]] = sz;
        R[L[sz]] = sz;
    }
    else
    {
        L[sz] = sz;
        R[sz] = sz;
        H[i] = sz;
    }
    U[sz] = U[j];
    D[sz] = j;
    U[D[sz]] = sz;
    D[U[sz]] = sz;
    C[sz] = j;
    ROW[sz] = i;
    ++S[j];
    ++sz;
}
int ans;
void dfs(int k)
{
    if(R[head]==head)
    {
        if(ans>k) ans=k;
        return;
    }
    int s=INF,c;
    for (int t=R[head]; t!=head; t=R[t])
        if (S[t]<s) s=S[t],c=t;
    remove(c);
    for(int i=D[c]; i!=c; i=D[i])
    {
        O[k]=ROW[i];
        for(int j=R[i]; j!=i; j=R[j])
            remove(C[j]);
        dfs(k+1);
        for(int j=L[i]; j!=i; j=L[j])
            resume(C[j]);
    }
    resume(c);
}
int main()
{
    //freopen("1.txt","r",stdin);
    int t;
    cin>>t;
    while(t--)
    {
        int n,m,p,i,j,k,x1,y1,x2,y2;
        scanf("%d%d%d",&n,&m,&p);
        init(n*m);
        for(i=1;i<=p;i++)
        {
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            for(j=x1;j<x2;j++)
                for(k=y1+1;k<=y2;k++)
                    insert(i,j*m+k);
        }
        ans=INF;
        dfs(0);
        printf("%d\n",ans==INF?-1:ans);
    }
    return 0;
}


ZOJ 3209 Dancing Links

标签:style   blog   color   os   io   ar   for   2014   问题   

原文地址:http://blog.csdn.net/u011466175/article/details/38930491

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!