DLX hdu 3498


[マルチオーバーライド](Multiple Override)または[重複オーバーライド](Duplicate Override)の問題

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#define out(v) cout << #v << ": " << (v) << endl
using namespace std;
typedef long long LL;

const int max_size = 60 * 60;
const int maxint = 0x3f3f3f3f;
int L[max_size], R[max_size], U[max_size], D[max_size], CH[max_size];
int S[60];
int head, size;

void remove(const int &c) {
    for (int i = D[c]; i != c; i = D[i]) {
        L[R[i]] = L[i], R[L[i]] = R[i];
        --S[CH[i]];
    }
}
void resume(const int &c) {
    for (int i = U[c]; i != c; i = U[i]) {
        ++S[CH[i]];
        L[R[i]] = R[L[i]] = i;
    }
}
int H() {
    int cnt = 0;
    bool cover[60] = {false};
    for (int c = R[head]; c != head; c = R[c])
        if (!cover[c]) {
            cover[c] = true, ++cnt;
            for (int i = D[c]; i != c; i = D[i])
                for (int j = R[i]; j != i; j = R[j])
                    cover[CH[j]] = true;
        }
    return cnt;
}
int ans, ans_cnt;
void dfs(const int &k) {
    if (R[head] == head) {
        ans = min(ans, k);
        return;
    }
    int s(maxint), c;
    for (int t = R[head]; t != head; t = R[t]) {
        if (S[t] < s) s = S[t], c = t;
    }
    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 (k + 1 + H() < ans)
            dfs(k + 1);
        for (int j = L[i]; j != i; j = L[j])
            resume(j);
        resume(i);
    }
}
int node(int up, int down, int left, int right) {
    U[size] = up, D[size] = down;
    L[size] = left, R[size] = right;
    D[up] = U[down] = R[left] = L[right] = size;
    return size++;
}

bool G[60][60];
void init(int N, int M) {
    size = 0;
    head = node(0, 0, 0, 0);
    for (int j = 1; j <= M; ++j) {
        node(j, j, L[head], head);
        CH[j] = j, S[j] = 0;
    }
    int u, v;
    for (int u = 1; u <= N; ++u) {
        int row = -1;
        for (int v = 1; v <= N; ++v) {
            if (!G[u][v]) continue;
            if (row == -1) {
                row = node(U[CH[v]], CH[v], size, size);
                CH[row] = v, ++S[v];
            } else {
                int k = node(U[CH[v]], CH[v], L[row], row);
                CH[k] = v, ++S[v];
            }
        }
    }
}

int main()
{
    int N, M, u, v;
    while (scanf("%d%d", &N, &M) != EOF)
    {
        for (int i = 1; i <= N; ++i)
            for (int j = 1; j <= N; ++j)
                G[i][j] = (i == j ? true : false);
        while (M--) {
            scanf("%d%d", &u, &v);
            G[u][v] = G[v][u] = true;
        }
        init(N, N);
        ans = maxint;
        dfs(1);
        printf("%d
", ans - 1); } return 0; }