Dancing Links [Kuangbin带你飞] 模版及题解

学习资料: http://www.cnblogs.com/grenet/p/3145800.html

http://blog.csdn.net/mu399/article/details/7627862

2份模版 第一份精确覆盖 from POJ 3074

const int N = 9;
const int MAXN = N * N * N + 10;
const int MAXM = N * N * 4 + 10;
const int MAXNODE = MAXN * 4 + MAXM + 10;
int g[MAXN];
struct DLX
{
    int n,m,sz;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ansd,ans[MAXN];

    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        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 r,int c)
    {
        ++S[Col[++sz] = c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }

    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[Col[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[Col[U[D[j]] = D[U[j]] = j]];
        L[R[c]] = R[L[c]] = c;
    }

    bool Dance(int d)
    {
        if(R[0] == 0)
        {
            for(int i = 0 ;i < d ; i++)g[(ans[i] - 1) / N] = (ans[i] - 1) % 9 + 1;
            for(int i = 0 ;i < N * N ; i++)
            {
                printf("%d",g[i]);
               // if (i % N == N - 1) putchar('\n');
            }
            return true;
        }
        int c = R[0];
        for(int i = R[0] ; i != 0 ; i = R[i])
            if(S[i] < S[c])
                c = i;
        Remove(c);
        for(int i = D[c] ; i != c ; i = D[i])
        {
            ans[d] = Row[i];
            for(int j = R[i] ; j != i ; j = R[j]) Remove(Col[j]);
            if(Dance(d + 1))return true;
            for(int j = L[i] ; j != i ; j = L[j]) resume(Col[j]);
        }
        resume(c);
        return false;
    }
};
View Code

第二份重复覆盖 from HDU 2295

struct DLX
{
    int n,m,sz;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ands,ans[MAXN];

    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        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 r,int c)
    {
        ++S[Col[++sz] = c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }

    void Remove(int c)
    {
        for(int i = D[c] ; i != c ; i = D[i])
            L[R[i]] = L[i], R[L[i]] = R[i];
    }

    void resume(int c)
    {
        for(int i = U[c] ; i != c ; i = U[i])
            L[R[i]] = R[L[i]] = i;
    }

    bool v[MAXNODE];
    int f()
    {
        int ret = 0;
        for(int c = R[0] ; c != 0 ; c = R[c])v[c] = true;
        for(int c = R[0] ; c != 0 ; c = R[c])
            if(v[c])
            {
                ret++;
                v[c] = false;
                for(int i = D[c] ;i != c ;i = D[i])
                    for(int j = R[i] ;j != i ; j = R[j])
                        v[Col[j]] = false;
            }
        return ret;
    }

    bool Dance(int d)
    {
        if(d + f() > K)return false;
        if(R[0] == 0)return d <= K;
        int c = R[0];
        for(int i = R[0];i != 0;i = R[i])
            if(S[i] < S[c])
                c = i;
        for(int i = D[c];i != c;i = D[i])
        {
            Remove(i);
            for(int j = R[i] ; j != i ; j = R[j])Remove(j);
            if(Dance(d + 1))return true;
            for(int j = L[i] ; j != i ; j = L[j])resume(j);
            resume(i);
        }
        return false;
    }
};
View Code

HUST 1017 Exact cover

裸题

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int INF = 0x3f3f3f3f;
const int MAXN = 1010;
const int MAXM = 1010;
const int MAXNODE = MAXN * MAXN;
int g[MAXN];
struct DLX
{
    int n,m,sz;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ansd,ans[MAXN];

    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        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 r,int c)
    {
        ++S[Col[++sz] = c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }

    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[Col[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[Col[U[D[j]] = D[U[j]] = j]];
        L[R[c]] = R[L[c]] = c;
    }

    bool Dance(int d)
    {
        if(R[0] == 0)
        {
            printf("%d ",d);
            for (int i = 0 ; i < d ; i++)
                printf("%d%c",ans[i],i == d - 1 ? '\n' : ' ');
            return true;
        }
        int c = R[0];
        for(int i = R[0] ; i != 0 ; i = R[i])
            if(S[i] < S[c])
                c = i;
        Remove(c);
        for(int i = D[c] ; i != c ; i = D[i])
        {
            ans[d] = Row[i];
            for(int j = R[i] ; j != i ; j = R[j]) Remove(Col[j]);
            if(Dance(d + 1))return true;
            for(int j = L[i] ; j != i ; j = L[j]) resume(Col[j]);
        }
        resume(c);
        return false;
    }
};

DLX slover;
int N,M;

int main()
{
    //freopen("sample.txt","r",stdin);
    while (scanf("%d%d",&N,&M) != EOF)
    {
        slover.init(N,M);
        for (int i = 1 ; i <= N ; i++)
        {
            int cnt;
            scanf("%d",&cnt);
            while(cnt--)
            {
                int x;
                scanf("%d",&x);
                slover.link(i,x);
            }
        }
        if (!slover.Dance(0)) puts("NO");
        putchar('\n');
    }
    return 0;
}
View Code

ZOJ 3209 Treasure Map

每个矩形为行,对应的可以包含的为列

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int INF = 0x3f3f3f3f;
const int MAXN = 510;
const int MAXM = 1010;
const int MAXNODE = MAXN * MAXM;
struct DLX
{
    int n,m,sz;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ansd,ans[MAXN];

    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        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 r,int c)
    {
        ++S[Col[++sz] = c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }

    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[Col[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[Col[U[D[j]] = D[U[j]] = j]];
        L[R[c]] = R[L[c]] = c;
    }

    void Dance(int d)
    {
        if(ansd != -1 && d > ansd) return;
        if(R[0] == 0)
        {
            if (ansd == -1) ansd = d;
            else ansd = min(ansd,d);
            return;
        }
        int c = R[0];
        for(int i = R[0] ; i != 0 ; i = R[i])
            if(S[i] < S[c])
                c = i;
        Remove(c);
        for(int i = D[c] ; i != c ; i = D[i])
        {
            ans[d] = Row[i];
            for(int j = R[i] ; j != i ; j = R[j]) Remove(Col[j]);
            Dance(d + 1);
            for(int j = L[i] ; j != i ; j = L[j]) resume(Col[j]);
        }
        resume(c);
        return;
    }
};

DLX slover;
int N,M,Q;

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d%d",&N,&M,&Q);
        slover.init(Q,N * M);
        for (int i = 1 ; i <= Q ; i++)
        {
            int x1,y1,x2,y2;
            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++)
            {
                int pos = (j - 1) * M + k;
                slover.link(i,pos);
            }
        }
        slover.ansd = -1;
        slover.Dance(0);
        printf("%d\n",slover.ansd);
    }
    return 0;
}
View Code

HDU 2295 Radar

二分+DLX 

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 60;
const int MAXM = 60;
const int MAXNODE = MAXN * MAXM;
const double eps = 1e-10;
int K;
struct DLX
{
    int n,m,sz;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ands,ans[MAXN];

    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        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 r,int c)
    {
        ++S[Col[++sz] = c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }

    void Remove(int c)
    {
        for(int i = D[c] ; i != c ; i = D[i])
            L[R[i]] = L[i], R[L[i]] = R[i];
    }

    void resume(int c)
    {
        for(int i = U[c] ; i != c ; i = U[i])
            L[R[i]] = R[L[i]] = i;
    }

    bool v[MAXNODE];
    int f()
    {
        int ret = 0;
        for(int c = R[0] ; c != 0 ; c = R[c])v[c] = true;
        for(int c = R[0] ; c != 0 ; c = R[c])
            if(v[c])
            {
                ret++;
                v[c] = false;
                for(int i = D[c] ;i != c ;i = D[i])
                    for(int j = R[i] ;j != i ; j = R[j])
                        v[Col[j]] = false;
            }
        return ret;
    }

    bool Dance(int d)
    {
        if(d + f() > K)return false;
        if(R[0] == 0)return d <= K;
        int c = R[0];
        for(int i = R[0];i != 0;i = R[i])
            if(S[i] < S[c])
                c = i;
        for(int i = D[c];i != c;i = D[i])
        {
            Remove(i);
            for(int j = R[i] ; j != i ; j = R[j])Remove(j);
            if(Dance(d + 1))return true;
            for(int j = L[i] ; j != i ; j = L[j])resume(j);
            resume(i);
        }
        return false;
    }
};

DLX slover;
struct point
{
    int x,y;
}city[MAXN],station[MAXN];

inline double dis(point a,point b)
{
    return sqrt(1.0 * (a.x - b.x) * (a.x - b.x) + 1.0 * (a.y - b.y) * (a.y - b.y));
}

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        int n,m;
        scanf("%d%d%d",&n,&m,&K);
        for (int i = 0 ; i < n ; i++)scanf("%d%d",&city[i].x,&city[i].y);
        for (int i = 0 ; i < m ; i++)scanf("%d%d",&station[i].x,&station[i].y);
        double l = 0,r = 1e8;
        while (r - l > eps)
        {
            double mid = l + (r - l) / 2;
            slover.init(m,n);
            for (int i = 0 ; i < m ; i++)
            {
                for (int j = 0 ; j < n ; j++)
                {
                    double dist = dis(station[i],city[j]);
                    if (dist < mid - eps)
                        slover.Link(i + 1,j + 1);
                }
            }
            if (slover.Dance(0)) r = mid - eps;
            else l = mid + eps;
        }
        printf("%.6lf\n",l);
    }
    return 0;
}
View Code

FZU 1686 神龙的难题

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 250;
const int MAXM = 250;
const int MAXNODE = MAXN * MAXN;
const int INF = 0x3f3f3f3f;

struct DLX
{
    int n,m,sz;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ansd,ans[MAXN];

    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        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 r,int c)
    {
        ++S[Col[++sz] = c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }

    void Remove(int c)
    {
        for(int i = D[c] ; i != c ; i = D[i])
            L[R[i]] = L[i], R[L[i]] = R[i];
    }

    void resume(int c)
    {
        for(int i = U[c] ; i != c ; i = U[i])
            L[R[i]] = R[L[i]] = i;
    }

    bool v[MAXNODE];
    int f()
    {
        int ret = 0;
        for(int c = R[0] ; c != 0 ; c = R[c])v[c] = true;
        for(int c = R[0] ; c != 0 ; c = R[c])
            if(v[c])
            {
                ret++;
                v[c] = false;
                for(int i = D[c] ;i != c ;i = D[i])
                    for(int j = R[i] ;j != i ; j = R[j])
                        v[Col[j]] = false;
            }
        return ret;
    }

    void Dance(int d)
    {
        if(d + f() >= ansd)return;
        if(R[0] == 0)
        {
            ansd = min(ansd,d);
            return;
        }
        int c = R[0];
        for(int i = R[0];i != 0;i = R[i])
            if(S[i] < S[c])
                c = i;
        for(int i = D[c];i != c;i = D[i])
        {
            Remove(i);
            for(int j = R[i] ; j != i ; j = R[j])Remove(j);
            Dance(d + 1);
            for(int j = L[i] ; j != i ; j = L[j])resume(j);
            resume(i);
        }
        return;
    }
};

int id[30][30];
int N,M;
int ln,lm;
DLX slover;

int main()
{
    while (scanf("%d%d",&N,&M) != EOF)
    {
        int cas = 0;
        memset(id,0,sizeof(id));
        for (int i = 1 ; i <= N ; i++)
        {
            for (int j = 1 ; j <= M ; j++)
            {
                int x;
                scanf("%d",&x);
                if (x) id[i][j] = ++cas;
            }
        }
        scanf("%d%d",&ln,&lm);
        slover.init(N * M,cas);
        cas = 1;
        for (int i = 1 ; i <= N ; i++)
        {
            for (int j = 1 ; j <= M ; j++)
            {
                for (int stepx = 0 ; stepx < ln && i + stepx <= N ; stepx++)
                    for (int stepy = 0 ; stepy < lm && j + stepy <= M ; stepy++)
                {
                    if (id[i + stepx][j + stepy])
                        slover.Link(cas,id[i + stepx][j + stepy]);
                }
                cas++;
            }
        }
        slover.ansd = INF;
        slover.Dance(0);
        printf("%d\n",slover.ansd);
    }
    return 0;
}
View Code

POJ 1084 Square Destroyer

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXM = 210;
const int MAXN = 110;
const int MAXNODE = MAXN * MAXM;
const int INF = 0x3f3f3f3f;
struct DLX
{
    int n,m,sz;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ansd,ans[MAXN];

    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        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 r,int c)
    {
        ++S[Col[++sz] = c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }

    void Remove(int c)
    {
        for(int i = D[c] ; i != c ; i = D[i])
            L[R[i]] = L[i], R[L[i]] = R[i];
    }

    void resume(int c)
    {
        for(int i = U[c] ; i != c ; i = U[i])
            L[R[i]] = R[L[i]] = i;
    }

    bool v[MAXNODE];
    int f()
    {
        int ret = 0;
        for(int c = R[0] ; c != 0 ; c = R[c])v[c] = true;
        for(int c = R[0] ; c != 0 ; c = R[c])
            if(v[c])
            {
                ret++;
                v[c] = false;
                for(int i = D[c] ;i != c ;i = D[i])
                    for(int j = R[i] ;j != i ; j = R[j])
                        v[Col[j]] = false;
            }
        return ret;
    }

    void Dance(int d)
    {
        if(d + f() > ansd)return;
        if(R[0] == 0)
        {
            ansd = min(ansd,d);
        }
        int c = R[0];
        for(int i = R[0];i != 0;i = R[i])
            if(S[i] < S[c])
                c = i;
        for(int i = D[c];i != c;i = D[i])
        {
            Remove(i);
            for(int j = R[i] ; j != i ; j = R[j])Remove(j);
            Dance(d + 1);
            for(int j = L[i] ; j != i ; j = L[j])resume(j);
            resume(i);
        }
        return;
    }
};

DLX slover;
int n;
int a[20][20][20];
int id[50][50];
int b[200];
bool f[200];

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d",&n);
        int tot = (2 * n + 1) * n + n;
        for (int i = 0 ; i <= tot ; i++)  f[i] = true;
        int m,v;
        scanf("%d",&m);
        while (m--)
        {
            scanf("%d",&v);
            f[v] = false;
        }
        int num = 0;
        for (int i = 1 ; i <= n + 1 ; i++)
        {
            for (int j = 1;  j <= n ; j++)
                id[2 * i - 1][j] = ++num;
            if (i <= n)
            {
                for (int j = 0 ; j <= n ; j++)
                    id[2 * i][j] = ++num;
            }
        }
        int cnt = 0;
        for (int  i = 1 ; i <= tot ; i++)
        {
            if (f[i]) b[i] = ++cnt;
        }
        num = 0;
        memset(a,-1,sizeof(a));
        for (int i = 1;  i <= n ; i++)
        {
            for (int j = 1;  j <= n ; j++)
                for (int k = 1 ; i + k - 1 <= n && j + k - 1 <= n ; k++)
                {
                    bool flag = true;
                    for (int x = 0 ; x < k ; x++)
                        if (!f[id[2 * i - 1][j + x]]) flag = false;
                    for (int x = 0 ; x < k ; x++)
                        if (!f[id[2 * (i + k - 1) + 1][j + x]]) flag = false;
                    for (int x = 0 ; x < k ; x++)
                        if (!f[id[2 * (i + x)][j - 1]]) flag = false;
                    for (int x = 0 ; x < k ; x++)
                        if (!f[id[2 * (i + x)][j + k - 1]]) flag = false;
                    if (!flag) continue;
                    a[i][j][k] = ++num;
                }
        }
        slover.init(cnt,num);
        for (int i = 1 ; i <= n ; i++)
            for (int j = 1 ; j <= n ; j++)
        {
            for (int k = 1 ; i + k - 1 <= n && j + k - 1 <= n ; k++)
            {
                if (a[i][j][k] != -1)
                {
                    for (int x = 0 ; x < k ; x++)
                    {
                        slover.Link(b[id[2 * i - 1][j + x]],a[i][j][k]);
                        slover.Link(b[id[2 * (i + k - 1) + 1][j + x]],a[i][j][k]);
                        slover.Link(b[id[2 * (i + x)][j - 1]],a[i][j][k]);
                        slover.Link(b[id[2 * (i + x)][j + k - 1]],a[i][j][k]);
                    }
                }
            }
        }
        slover.ansd = INF;
        slover.Dance(0);
        printf("%d\n",slover.ansd);
    }
    return 0;
}
View Code

POJ 3074 Sudoku

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int INF = 0x3f3f3f3f;
const int N = 9;
const int MAXN = N * N * N + 10;
const int MAXM = N * N * 4 + 10;
const int MAXNODE = MAXN * 4 + MAXM + 10;
int g[MAXN];
struct DLX
{
    int n,m,sz;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ansd,ans[MAXN];

    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        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 r,int c)
    {
        ++S[Col[++sz] = c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }

    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[Col[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[Col[U[D[j]] = D[U[j]] = j]];
        L[R[c]] = R[L[c]] = c;
    }

    bool Dance(int d)
    {
        if(R[0] == 0)
        {
            for(int i = 0 ;i < d ; i++)g[(ans[i] - 1) / N] = (ans[i] - 1) % 9 + 1;
            for(int i = 0 ;i < N * N ; i++)
            {
                printf("%d",g[i]);
               // if (i % N == N - 1) putchar('\n');
            }
            return true;
        }
        int c = R[0];
        for(int i = R[0] ; i != 0 ; i = R[i])
            if(S[i] < S[c])
                c = i;
        Remove(c);
        for(int i = D[c] ; i != c ; i = D[i])
        {
            ans[d] = Row[i];
            for(int j = R[i] ; j != i ; j = R[j]) Remove(Col[j]);
            if(Dance(d + 1))return true;
            for(int j = L[i] ; j != i ; j = L[j]) resume(Col[j]);
        }
        resume(c);
        return false;
    }
};

DLX slover;
int G[20][20];
char str[100];

void place(int &r,int &c1,int &c2,int &c3,int &c4,int i,int j,int k)
{
    r = (i * N + j) * N + k;
    c1 = i * N + j + 1;
    c2 = N * N + (i * N + k);
    c3 = N * N * 2 + (j * N + k);
    c4 = N * N * 3 + ((i / 3) * 3 + (j / 3)) * N + k;
}

int main()
{
    //freopen("sample.txt","r",stdin);
    while (scanf("%s",str) != EOF)
    {
        if (strcmp(str,"end") == 0) break;
        int cas = 0;
        for (int i = 0 ; i < 9 ; i++)
        {
            for (int j = 0 ; j < 9 ; j++)
            {
                char tmp = str[cas];
                cas++;
                if (tmp == '.') G[i][j] = -1;
                else G[i][j] = tmp - '0';
            }
        }
        int r,c1,c2,c3,c4;
        slover.init(N * N * N ,N * N * 4);
        for (int i = 0 ; i < N ; i++)
            for (int j = 0 ; j < N ; j++)
                for (int k = 1 ; k <= 9 ; k++)
        {
            if (G[i][j] == -1 || G[i][j] == k)
            {
                place(r,c1,c2,c3,c4,i,j,k);
                slover.link(r,c1);
                slover.link(r,c2);
                slover.link(r,c3);
                slover.link(r,c4);
            }
        }
        slover.Dance(0);
        putchar('\n');
    }
    return 0;
}
View Code

ZOJ 3122 Sudoku

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int INF = 0x3f3f3f3f;
const int N = 16;
const int MAXN = N * N * N + 10;
const int MAXM = N * N * 4 + 10;
const int MAXNODE = MAXN * 4 + MAXM + 10;
char g[MAXN];
struct DLX
{
    int n,m,sz;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ansd,ans[MAXN];

    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        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 r,int c)
    {
        ++S[Col[++sz] = c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }

    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[Col[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[Col[U[D[j]] = D[U[j]] = j]];
        L[R[c]] = R[L[c]] = c;
    }

    bool Dance(int d)
    {
        if(R[0] == 0)
        {
            for(int i = 0 ;i < d ; i++)g[(ans[i] - 1) / N] = (ans[i] - 1) % N + 'A';
            for(int i = 0 ;i < N * N ; i++)
            {
                printf("%c",g[i]);
                if (i % N == N - 1) putchar('\n');
            }
            return true;
        }
        int c = R[0];
        for(int i = R[0] ; i != 0 ; i = R[i])
            if(S[i] < S[c])
                c = i;
        Remove(c);
        for(int i = D[c] ; i != c ; i = D[i])
        {
            ans[d] = Row[i];
            for(int j = R[i] ; j != i ; j = R[j]) Remove(Col[j]);
            if(Dance(d + 1))return true;
            for(int j = L[i] ; j != i ; j = L[j]) resume(Col[j]);
        }
        resume(c);
        return false;
    }
};

void place(int &r,int &c1,int &c2,int &c3,int &c4,int i,int j,int k)
{
    r = (i * N + j) * N + k;
    c1 = i * N + j + 1;
    c2 = N * N + i * N + k;
    c3 = N * N * 2 + j * N + k;
    c4 = N * N * 3 + ((i / 4) * 4 + j / 4) * N + k;
}

DLX slover;
char str[30][30];

int main()
{
    //freopen("sample.txt","r",stdin);
    bool first = true;
    while (scanf("%s",str[0]) == 1)
    {
        if (first) first = false;
        else putchar('\n');
        for (int i = 1 ; i < 16 ; i++)scanf("%s",str[i]);
        slover.init(N * N * N,N * N * 4);
        int r,c1,c2,c3,c4;
        for (int i = 0 ; i < N ; i++)
            for(int j = 0 ; j < N ; j++)
                for (int k = 1 ; k <= N ; k++)
        {
           if (str[i][j] == '-' || str[i][j] == 'A' + k - 1)
           {
                place(r,c1,c2,c3,c4,i,j,k);
                slover.link(r,c1);
                slover.link(r,c2);
                slover.link(r,c3);
                slover.link(r,c4);
           }
        }
        slover.Dance(0);
    }
    return 0;
}
View Code

HDU 4069 Squiggly Sudoku

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int N = 9; //3*3数独
const int MAXN = N*N*N + 10;
const int MAXM = N*N*4 + 10;
const int MAXNODE = MAXN*4 + MAXM + 10;
char g[MAXN];
int cnt;
struct DLX
{
    int n,m,sz;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ansd,ans[MAXN];

    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        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 r,int c)
    {
        ++S[Col[++sz]=c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }

    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[Col[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[Col[U[D[j]]=D[U[j]]=j]];
        L[R[c]] = R[L[c]] = c;
    }

    void Dance(int d)
    {
        if(cnt > 1)return;
        if(R[0] == 0)
        {
            for(int i = 0;i < d;i++)g[(ans[i]-1)/9] = (ans[i]-1)%9 + '1';
            cnt++;
            return;
        }
        int c = R[0];
        for(int i = R[0];i != 0;i = R[i])
            if(S[i] < S[c])
                c = i;
        Remove(c);
        for(int i = D[c];i != c;i = D[i])
        {
            ans[d] = Row[i];
            for(int j = R[i];j != i;j = R[j])Remove(Col[j]);
            Dance(d+1);
            if(cnt > 1)return;
            for(int j = L[i];j != i;j = L[j])resume(Col[j]);
        }
        resume(c);
    }
};

DLX slover;
int id[30][30];
int a[30][30];

void bfs(int sx,int sy,int d)
{
    queue<pair<int,int> >q;
    q.push(make_pair(sx,sy));
    id[sx][sy] = d;
    while(!q.empty())
    {
        pair<int,int> tmp = q.front();
        int x = tmp.first;
        int y = tmp.second;
        q.pop();
        if(x > 0 && ((a[x][y]% 32) / 16) == 0)
            if(id[x - 1][y] == -1)
            {
                id[x - 1][y] = d;
                q.push(make_pair(x - 1,y));
            }
        if(x < N - 1 && ((a[x][y] % 128) / 64) == 0)
            if(id[x + 1][y] == -1)
            {
                id[x + 1][y] = d;
                q.push(make_pair(x + 1,y));
            }
        if(y > 0 && ((a[x][y]) / 128) == 0)
            if(id[x][y - 1] == -1)
            {
                id[x][y - 1] = d;
                q.push(make_pair(x,y - 1));
            }
        if(y < N - 1 && ((a[x][y] % 64) / 32) == 0)
            if(id[x][y + 1] == -1)
            {
                id[x][y + 1] = d;
                q.push(make_pair(x,y + 1));
            }
    }
}

int main()
{
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        for (int i = 0 ; i < N ; i++)
            for (int j = 0 ; j < N ; j++) scanf("%d",&a[i][j]);
        memset(id,-1,sizeof(id));
        int index = 0;
        for (int i = 0 ; i < N ; i++)
            for (int j = 0 ; j < N ; j++)
        {
            if (id[i][j] == -1)
                bfs(i,j,++index);
        }

     /*   for (int i = 0 ; i < N ; i++)
        {
            for (int j = 0; j < N ; j++)
                printf("%d ",id[i][j]);
            putchar('\n');
        }
    */
        slover.init(N * N * N,N * N * 4);
        for (int i = 0 ; i < N ; i++)
            for (int j = 0 ; j < N ; j++)
                for (int k = 1 ; k <= N ; k++)
        {
            if (a[i][j] % 16 != 0 && a[i][j] % 16 != k) continue;
            int r = (i * N + j) * N + k;
            int c1 = i * N + j + 1;
            int c2 = N * N  + i * N + k;
            int c3 = N * N * 2 + j * N + k;
            int c4 = N * N * 3 + (id[i][j] - 1) * N + k;
            slover.Link(r,c1);
            slover.Link(r,c2);
            slover.Link(r,c3);
            slover.Link(r,c4);
        }
        cnt = 0;
        slover.Dance(0);
        printf("Case %d:\n",kase++);
        if (cnt == 0) puts("No solution");
        else if (cnt > 1) puts("Multiple Solutions");
        else
        {
            for (int i = 0 ; i < N * N ; i++)
            {
                printf("%c",g[i]);
                if (i % N == N - 1) putchar('\n');
            }
        }

    }
    return 0;
}
View Code

HDU 3335 Divisibility 这个题不是DLX不知道为啥放到专题里了。也放到这吧

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 2010;
const int MAXM = MAXN * 20;
struct Edge
{
    int u,v,next;
    int w;
}edge[MAXM];
int head[MAXN],tot;

void init()
{
    memset(head,-1,sizeof(head));
    tot = 0;
}

void add_edge(int u,int v,int w)
{
    edge[tot].u = u;
    edge[tot].v = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot++;
}

int linker[MAXN];
bool used[MAXN];
int NX;

bool dfs(int u)
{
    for (int i = head[u] ; i != -1 ; i = edge[i].next)
    {
        int v = edge[i].v;
        if (!used[v])
        {
            used[v] = true;
            if (linker[v] == -1 || dfs(linker[v]))
            {
                linker[v] = u;
                return true;
            }
        }
    }
    return false;
}

int calcu()
{
    memset(linker,-1,sizeof(linker));
    int ret = 0;
    for (int i = 0 ; i < NX ; i++)
    {
        memset(used,false,sizeof(used));
        if (dfs(i)) ret++;
    }
    return ret;
}

int N;
LL src[MAXN];

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d",&N);
        for (int i = 0;  i< N ; i++) scanf("%I64d",&src[i]);
        sort(src,src + N);
        N = unique(src,src + N) - src;
        NX = N;
        init();
        for (int i = 0 ; i < NX ; i++)
        {
            for (int j = 0 ; j < NX ; j++)
            {
                if (i == j) continue;
                if (src[j] % src[i] == 0) add_edge(i,j,9797);
            }
        }
        int ret = calcu();
        printf("%d\n",NX - ret);
    }
    return 0;
}
View Code

HDU 4979 A simple math problem.

DLX 打表

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
const int MAXN = 15 * 15 + 2010;
const int MAXM = 15 * 15 + 2010;
const int MAXNODE = MAXN * MAXM;
const int INF = 0x3f3f3f3f;
int a[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,2,3,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,2,6,0,0,0,0,0,0,0,2,3,4,0,0,0
,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,
0,0,0,0,0,3,10,0,0,0,0,0,0,0,2,4,10,0,0,0,0,0,0,2,3,4,5,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,3,15,0,0,0,0,0,0,0,2,6,20,0,0,0,0,0,0,2,3,6,15,0,0,0,0,0,2,3,4,5,6,0,0,0,0,
1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,4,21,0,0,0,0,0,0,0,3,7,35,0,0,0,0,0,0,
2,5,12,35,0,0,0,0,0,2,3,5,9,21,0,0,0,0,2,3,4,5,6,7,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,4,28,
0,0,0,0,0,0,0,3,11,56,0,0,0,0,0,0,2,6,14,70,0,0,0,0,0,2,4,8,0,56,0,0,0,0,2,3,4,7,12,28,0,0,0,2,3,4,5,6,7,8,0,0,1,1,1,1,1,1,1,1,
    
};
/*struct DLX
{
    int n,m,sz;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ans[MAXN];
    LL ansd;

    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        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 r,int c)
    {
        ++S[Col[++sz] = c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }

    void Remove(int c)
    {
        for(int i = D[c] ; i != c ; i = D[i])
            L[R[i]] = L[i], R[L[i]] = R[i];
    }

    void resume(int c)
    {
        for(int i = U[c] ; i != c ; i = U[i])
            L[R[i]] = R[L[i]] = i;
    }

    bool v[MAXNODE];
    int f()
    {
        int ret = 0;
        for(int c = R[0] ; c != 0 ; c = R[c])v[c] = true;
        for(int c = R[0] ; c != 0 ; c = R[c])
            if(v[c])
            {
                ret++;
                v[c] = false;
                for(int i = D[c] ;i != c ;i = D[i])
                    for(int j = R[i] ;j != i ; j = R[j])
                        v[Col[j]] = false;
            }
        return ret;
    }

    void Dance(int d)
    {
        if(d + f() >= ansd)return;
        if(R[0] == 0)
        {
            ansd = min(ansd,1LL * d);
            return;
        }
        int c = R[0];
        for(int i = R[0];i != 0;i = R[i])
            if(S[i] < S[c])
                c = i;
        for(int i = D[c];i != c;i = D[i])
        {
            Remove(i);
            for(int j = R[i] ; j != i ; j = R[j])Remove(j);
            Dance(d + 1);
            for(int j = L[i] ; j != i ; j = L[j])resume(j);
            resume(i);
        }
        return;
    }
};

DLX slover;
int a[MAXN],b[MAXN];
LL C[20][20];
void init2()
{
    C[0][0] = 1;
    for (int i = 1 ; i < 20 ; i++)
    {
        C[i][0] = C[i][i] = 1;
        for (int j = 1 ; j < i ; j++)
            C[i][j] = C[i -1][j] + C[i -1][j - 1];
    }
}

int main()
{
    init2();
    int N,M,R;
    int kase = 1;
    for (int n = 0 ; n < 9 ; n++)
        for (int m = 0 ; m < 9 ; m++)
            for (int r = 0 ; r < 9 ; r++)
    {
        if (n == 0 && m == 0 && r == 0){ printf("0, "); continue;}
        if (!(r <= m && m <= n)) {printf("0, "); continue;}
        if (n == 8 && m == 5 && r == 4) {printf("20, "); continue;}
        int cnt1 = 0;
        int cnt2 = 0;
        for (int i = 0 ; i < (1 << n) ; i++)
        {
            int cc = 0;
            for (int j = 0 ; j < n ; j++)
                if (i & (1 << j)) cc++;
            if (cc == m) a[++cnt1] = i;
            if (cc == r) b[++cnt2] = i;
        }
        slover.init(cnt1,cnt2);
        for (int i = 1 ; i <= cnt1 ; i++)
            for (int j = 1 ; j <= cnt2 ; j++)
                if ((a[i] | b[j]) == a[i])
                    slover.Link(i,j);
        LL tmp = C[n][r];
        LL tmp2 = C[m][n];
        slover.ansd = tmp;
        slover.Dance(0);
        printf("%d, ",slover.ansd);
    }
    return 0;
}*/

int main()
{
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        int n,m,r;
        scanf("%d%d%d",&n,&m,&r);
        if (n == 8 && m == 5 && r == 4) printf("Case #%d: %d\n",kase++,20);
        else 
        {
            printf("Case #%d: %d\n",kase++,a[n * 9 * 9 + m * 9 + r]);
        }
    }
    return 0;
}
View Code

HDU 5046 Airport

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
const int MAXN = 70;
const int MAXM = 70;
const int MAXNODE = MAXN * MAXM;
const int INF = 0x3f3f3f3f;
int N,K;

struct DLX
{
    int n,m,sz;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ans[MAXN];
    LL ansd;

    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        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 r,int c)
    {
        ++S[Col[++sz] = c];
        Row[sz] = r;
        D[sz] = D[c];
        U[D[c]] = sz;
        U[sz] = c;
        D[c] = sz;
        if(H[r] < 0)H[r] = L[sz] = R[sz] = sz;
        else
        {
            R[sz] = R[H[r]];
            L[R[H[r]]] = sz;
            L[sz] = H[r];
            R[H[r]] = sz;
        }
    }

    void Remove(int c)
    {
        for(int i = D[c] ; i != c ; i = D[i])
            L[R[i]] = L[i], R[L[i]] = R[i];
    }

    void resume(int c)
    {
        for(int i = U[c] ; i != c ; i = U[i])
            L[R[i]] = R[L[i]] = i;
    }

    bool v[MAXNODE];
    int f()
    {
        int ret = 0;
        for(int c = R[0] ; c != 0 ; c = R[c])v[c] = true;
        for(int c = R[0] ; c != 0 ; c = R[c])
            if(v[c])
            {
                ret++;
                v[c] = false;
                for(int i = D[c] ;i != c ;i = D[i])
                    for(int j = R[i] ;j != i ; j = R[j])
                        v[Col[j]] = false;
            }
        return ret;
    }

    void Dance(int d)
    {
        if (ansd <= K) return;
        if(d + f() >= ansd)return;
        if(R[0] == 0)
        {
            if (ansd > d) ansd = d;
            return;
        }
        int c = R[0];
        for(int i = R[0];i != 0;i = R[i])
            if(S[i] < S[c])
                c = i;
        for(int i = D[c];i != c;i = D[i])
        {
            Remove(i);
            for(int j = R[i] ; j != i ; j = R[j])Remove(j);
            Dance(d + 1);
            for(int j = L[i] ; j != i ; j = L[j])resume(j);
            resume(i);
        }
        return;
    }
};

DLX slover;
struct point
{
    LL x,y;
}src[MAXN];

bool judge(LL mid)
{
    slover.init(N,N);
    for (int i = 1 ; i <= N ; i++)
    {
        for (int j = 1 ; j <= N ; j++)
        {
            LL dis = 1LL * abs(src[i].x - src[j].x) + 1LL * abs(src[i].y - src[j].y);
            if (dis <= mid) slover.Link(i,j);
        }
    }
    slover.ansd = 1e14;
    slover.Dance(0);
    if (slover.ansd <= K) return true;
    return false;
}


int main()
{
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d",&N,&K);
        for (int i = 1 ; i <= N ; i++) scanf("%I64d%I64d",&src[i].x,&src[i].y);
        LL L = 0,R = 1e12;
        LL ans = 0;
        while (L < R)
        {
            LL mid = L +(R - L) / 2;
            if (judge(mid)) R = mid;
            else L = mid + 1;
        }
    //    int ans = R;
    //    if (judge(R - 1)) ans = R - 1;
        printf("Case #%d: %I64d\n",kase++,L);
    }
    return 0;
}
View Code

 

posted @ 2015-10-06 22:29  Commence  阅读(379)  评论(0编辑  收藏  举报